forked from OSchip/llvm-project
[ORC] Re-apply r345077 with fixes to remove ambiguity in lookup calls.
llvm-svn: 345098
This commit is contained in:
parent
7c6344a64f
commit
23cb2e7f77
|
@ -40,6 +40,18 @@ class SymbolRef;
|
|||
/// Represents an address in the target process's address space.
|
||||
using JITTargetAddress = uint64_t;
|
||||
|
||||
/// Convert a JITTargetAddress to a pointer.
|
||||
template <typename T> T jitTargetAddressToPointer(JITTargetAddress Addr) {
|
||||
static_assert(std::is_pointer<T>::value, "T must be a pointer type");
|
||||
uintptr_t IntPtr = static_cast<uintptr_t>(Addr);
|
||||
assert(IntPtr == Addr && "JITTargetAddress value out of range for uintptr_t");
|
||||
return reinterpret_cast<T>(IntPtr);
|
||||
}
|
||||
|
||||
template <typename T> JITTargetAddress pointerToJITTargetAddress(T *Ptr) {
|
||||
return static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(Ptr));
|
||||
}
|
||||
|
||||
/// Flags for symbols in the JIT.
|
||||
class JITSymbolFlags {
|
||||
public:
|
||||
|
|
|
@ -54,8 +54,8 @@ using SymbolFlagsMap = DenseMap<SymbolStringPtr, JITSymbolFlags>;
|
|||
/// symbols to be obtained for logging.
|
||||
using SymbolDependenceMap = DenseMap<JITDylib *, SymbolNameSet>;
|
||||
|
||||
/// A list of JITDylib pointers.
|
||||
using JITDylibList = std::vector<JITDylib *>;
|
||||
/// A list of (JITDylib*, bool) pairs.
|
||||
using JITDylibSearchList = std::vector<std::pair<JITDylib *, bool>>;
|
||||
|
||||
/// Render a SymbolStringPtr.
|
||||
raw_ostream &operator<<(raw_ostream &OS, const SymbolStringPtr &Sym);
|
||||
|
@ -85,8 +85,8 @@ raw_ostream &operator<<(raw_ostream &OS, const SymbolDependenceMap &Deps);
|
|||
/// Render a MaterializationUnit.
|
||||
raw_ostream &operator<<(raw_ostream &OS, const MaterializationUnit &MU);
|
||||
|
||||
/// Render a JITDylibList.
|
||||
raw_ostream &operator<<(raw_ostream &OS, const JITDylibList &JDs);
|
||||
/// Render a JITDylibSearchList.
|
||||
raw_ostream &operator<<(raw_ostream &OS, const JITDylibSearchList &JDs);
|
||||
|
||||
/// Callback to notify client that symbols have been resolved.
|
||||
using SymbolsResolvedCallback = std::function<void(Expected<SymbolMap>)>;
|
||||
|
@ -351,14 +351,15 @@ using SymbolAliasMap = DenseMap<SymbolStringPtr, SymbolAliasMapEntry>;
|
|||
class ReExportsMaterializationUnit : public MaterializationUnit {
|
||||
public:
|
||||
/// SourceJD is allowed to be nullptr, in which case the source JITDylib is
|
||||
/// taken to be whatever JITDylib these definitions are materialized in. This
|
||||
/// is useful for defining aliases within a JITDylib.
|
||||
/// taken to be whatever JITDylib these definitions are materialized in (and
|
||||
/// MatchNonExported has no effect). This is useful for defining aliases
|
||||
/// within a JITDylib.
|
||||
///
|
||||
/// Note: Care must be taken that no sets of aliases form a cycle, as such
|
||||
/// a cycle will result in a deadlock when any symbol in the cycle is
|
||||
/// resolved.
|
||||
ReExportsMaterializationUnit(JITDylib *SourceJD, SymbolAliasMap Aliases,
|
||||
VModuleKey K);
|
||||
ReExportsMaterializationUnit(JITDylib *SourceJD, bool MatchNonExported,
|
||||
SymbolAliasMap Aliases, VModuleKey K);
|
||||
|
||||
StringRef getName() const override;
|
||||
|
||||
|
@ -368,6 +369,7 @@ private:
|
|||
static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases);
|
||||
|
||||
JITDylib *SourceJD = nullptr;
|
||||
bool MatchNonExported = false;
|
||||
SymbolAliasMap Aliases;
|
||||
};
|
||||
|
||||
|
@ -385,16 +387,19 @@ private:
|
|||
inline std::unique_ptr<ReExportsMaterializationUnit>
|
||||
symbolAliases(SymbolAliasMap Aliases, VModuleKey K = VModuleKey()) {
|
||||
return llvm::make_unique<ReExportsMaterializationUnit>(
|
||||
nullptr, std::move(Aliases), std::move(K));
|
||||
nullptr, true, std::move(Aliases), std::move(K));
|
||||
}
|
||||
|
||||
/// Create a materialization unit for re-exporting symbols from another JITDylib
|
||||
/// with alternative names/flags.
|
||||
/// If MatchNonExported is true then non-exported symbols from SourceJD can be
|
||||
/// re-exported. If it is false, attempts to re-export a non-exported symbol
|
||||
/// will result in a "symbol not found" error.
|
||||
inline std::unique_ptr<ReExportsMaterializationUnit>
|
||||
reexports(JITDylib &SourceJD, SymbolAliasMap Aliases,
|
||||
VModuleKey K = VModuleKey()) {
|
||||
bool MatchNonExported = false, VModuleKey K = VModuleKey()) {
|
||||
return llvm::make_unique<ReExportsMaterializationUnit>(
|
||||
&SourceJD, std::move(Aliases), std::move(K));
|
||||
&SourceJD, MatchNonExported, std::move(Aliases), std::move(K));
|
||||
}
|
||||
|
||||
/// Build a SymbolAliasMap for the common case where you want to re-export
|
||||
|
@ -411,13 +416,14 @@ public:
|
|||
/// Create a reexports generator. If an Allow predicate is passed, only
|
||||
/// symbols for which the predicate returns true will be reexported. If no
|
||||
/// Allow predicate is passed, all symbols will be exported.
|
||||
ReexportsGenerator(JITDylib &SourceJD,
|
||||
ReexportsGenerator(JITDylib &SourceJD, bool MatchNonExported = false,
|
||||
SymbolPredicate Allow = SymbolPredicate());
|
||||
|
||||
SymbolNameSet operator()(JITDylib &JD, const SymbolNameSet &Names);
|
||||
|
||||
private:
|
||||
JITDylib &SourceJD;
|
||||
bool MatchNonExported = false;
|
||||
SymbolPredicate Allow;
|
||||
};
|
||||
|
||||
|
@ -536,16 +542,18 @@ public:
|
|||
/// as the first in the search order (instead of this dylib) ensures that
|
||||
/// definitions within this dylib resolve to the lazy-compiling stubs,
|
||||
/// rather than immediately materializing the definitions in this dylib.
|
||||
void setSearchOrder(JITDylibList NewSearchOrder,
|
||||
bool SearchThisJITDylibFirst = true);
|
||||
void setSearchOrder(JITDylibSearchList NewSearchOrder,
|
||||
bool SearchThisJITDylibFirst = true,
|
||||
bool MatchNonExportedInThisDylib = true);
|
||||
|
||||
/// Add the given JITDylib to the search order for definitions in this
|
||||
/// JITDylib.
|
||||
void addToSearchOrder(JITDylib &JD);
|
||||
void addToSearchOrder(JITDylib &JD, bool MatcNonExported = false);
|
||||
|
||||
/// Replace OldJD with NewJD in the search order if OldJD is present.
|
||||
/// Otherwise this operation is a no-op.
|
||||
void replaceInSearchOrder(JITDylib &OldJD, JITDylib &NewJD);
|
||||
void replaceInSearchOrder(JITDylib &OldJD, JITDylib &NewJD,
|
||||
bool MatchNonExported = false);
|
||||
|
||||
/// Remove the given JITDylib from the search order for this JITDylib if it is
|
||||
/// present. Otherwise this operation is a no-op.
|
||||
|
@ -554,7 +562,7 @@ public:
|
|||
/// Do something with the search order (run under the session lock).
|
||||
template <typename Func>
|
||||
auto withSearchOrderDo(Func &&F)
|
||||
-> decltype(F(std::declval<const JITDylibList &>()));
|
||||
-> decltype(F(std::declval<const JITDylibSearchList &>()));
|
||||
|
||||
/// Define all symbols provided by the materialization unit to be part of this
|
||||
/// JITDylib.
|
||||
|
@ -642,12 +650,12 @@ private:
|
|||
const SymbolNameSet &Names);
|
||||
|
||||
void lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q,
|
||||
SymbolNameSet &Unresolved, JITDylib *MatchNonExportedInJD,
|
||||
bool MatchNonExported, MaterializationUnitList &MUs);
|
||||
SymbolNameSet &Unresolved, bool MatchNonExported,
|
||||
MaterializationUnitList &MUs);
|
||||
|
||||
void lodgeQueryImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
|
||||
SymbolNameSet &Unresolved, JITDylib *MatchNonExportedInJD,
|
||||
bool MatchNonExported, MaterializationUnitList &MUs);
|
||||
SymbolNameSet &Unresolved, bool MatchNonExported,
|
||||
MaterializationUnitList &MUs);
|
||||
|
||||
LookupImplActionFlags
|
||||
lookupImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
|
||||
|
@ -682,7 +690,7 @@ private:
|
|||
UnmaterializedInfosMap UnmaterializedInfos;
|
||||
MaterializingInfosMap MaterializingInfos;
|
||||
GeneratorFunction DefGenerator;
|
||||
JITDylibList SearchOrder;
|
||||
JITDylibSearchList SearchOrder;
|
||||
};
|
||||
|
||||
/// An ExecutionSession represents a running JIT program.
|
||||
|
@ -766,6 +774,10 @@ public:
|
|||
|
||||
/// Search the given JITDylib list for the given symbols.
|
||||
///
|
||||
/// SearchOrder lists the JITDylibs to search. For each dylib, the associated
|
||||
/// boolean indicates whether the search should match against non-exported
|
||||
/// (hidden visibility) symbols in that dylib (true means match against
|
||||
/// non-exported symbols, false means do not match).
|
||||
///
|
||||
/// The OnResolve callback will be called once all requested symbols are
|
||||
/// resolved, or if an error occurs prior to resolution.
|
||||
|
@ -782,19 +794,9 @@ public:
|
|||
/// dependenant symbols for this query (e.g. it is being made by a top level
|
||||
/// client to get an address to call) then the value NoDependenciesToRegister
|
||||
/// can be used.
|
||||
///
|
||||
/// If the MatchNonExportedInJD pointer is non-null, then the lookup will find
|
||||
/// non-exported symbols defined in the JITDylib pointed to by
|
||||
/// MatchNonExportedInJD.
|
||||
/// If MatchNonExported is true the lookup will find non-exported symbols in
|
||||
/// any JITDylib (setting MatchNonExportedInJD is redundant in such cases).
|
||||
/// If MatchNonExported is false and MatchNonExportedInJD is null,
|
||||
/// non-exported symbols will never be found.
|
||||
void lookup(const JITDylibList &JDs, SymbolNameSet Symbols,
|
||||
void lookup(const JITDylibSearchList &SearchOrder, SymbolNameSet Symbols,
|
||||
SymbolsResolvedCallback OnResolve, SymbolsReadyCallback OnReady,
|
||||
RegisterDependenciesFunction RegisterDependencies,
|
||||
JITDylib *MatchNonExportedInJD = nullptr,
|
||||
bool MatchNonExported = false);
|
||||
RegisterDependenciesFunction RegisterDependencies);
|
||||
|
||||
/// Blocking version of lookup above. Returns the resolved symbol map.
|
||||
/// If WaitUntilReady is true (the default), will not return until all
|
||||
|
@ -803,24 +805,29 @@ public:
|
|||
/// or an error occurs. If WaitUntilReady is false and an error occurs
|
||||
/// after resolution, the function will return a success value, but the
|
||||
/// error will be reported via reportErrors.
|
||||
Expected<SymbolMap> lookup(const JITDylibList &JDs,
|
||||
Expected<SymbolMap> lookup(const JITDylibSearchList &SearchOrder,
|
||||
const SymbolNameSet &Symbols,
|
||||
RegisterDependenciesFunction RegisterDependencies =
|
||||
NoDependenciesToRegister,
|
||||
bool WaitUntilReady = true,
|
||||
JITDylib *MatchNonExportedInJD = nullptr,
|
||||
bool MatchNonExported = false);
|
||||
bool WaitUntilReady = true);
|
||||
|
||||
/// Convenience version of blocking lookup.
|
||||
/// Performs a single-symbol lookup.
|
||||
Expected<JITEvaluatedSymbol> lookup(const JITDylibList &JDs,
|
||||
SymbolStringPtr Symbol,
|
||||
bool MatchNonExported = false);
|
||||
/// Searches each of the JITDylibs in the search order in turn for the given
|
||||
/// symbol.
|
||||
Expected<JITEvaluatedSymbol> lookup(const JITDylibSearchList &SearchOrder,
|
||||
SymbolStringPtr Symbol);
|
||||
|
||||
/// Convenience version of blocking lookup.
|
||||
/// Performs a single-symbol lookup, auto-interning the given symbol name.
|
||||
Expected<JITEvaluatedSymbol> lookup(const JITDylibList &JDs, StringRef Symbol,
|
||||
bool MatchNonExported = false);
|
||||
/// Searches each of the JITDylibs in the search order in turn for the given
|
||||
/// symbol. The search will not find non-exported symbols.
|
||||
Expected<JITEvaluatedSymbol> lookup(ArrayRef<JITDylib *> SearchOrder,
|
||||
SymbolStringPtr Symbol);
|
||||
|
||||
/// Convenience version of blocking lookup.
|
||||
/// Searches each of the JITDylibs in the search order in turn for the given
|
||||
/// symbol. The search will not find non-exported symbols.
|
||||
Expected<JITEvaluatedSymbol> lookup(ArrayRef<JITDylib *> SearchOrder,
|
||||
StringRef Symbol);
|
||||
|
||||
/// Materialize the given unit.
|
||||
void dispatchMaterialization(JITDylib &JD,
|
||||
|
@ -866,7 +873,7 @@ private:
|
|||
|
||||
template <typename Func>
|
||||
auto JITDylib::withSearchOrderDo(Func &&F)
|
||||
-> decltype(F(std::declval<const JITDylibList &>())) {
|
||||
-> decltype(F(std::declval<const JITDylibSearchList &>())) {
|
||||
return ES.runSessionLocked([&]() { return F(SearchOrder); });
|
||||
}
|
||||
|
||||
|
|
|
@ -144,7 +144,7 @@ public:
|
|||
/// LLLazyJIT with the given number of compile threads.
|
||||
static Expected<std::unique_ptr<LLLazyJIT>>
|
||||
Create(JITTargetMachineBuilder JTMB, DataLayout DL,
|
||||
unsigned NumCompileThreads = 0);
|
||||
JITTargetAddress ErrorAddr, unsigned NumCompileThreads = 0);
|
||||
|
||||
/// Set an IR transform (e.g. pass manager pipeline) to run on each function
|
||||
/// when it is compiled.
|
||||
|
|
|
@ -157,7 +157,7 @@ void CompileOnDemandLayer::emit(MaterializationResponsibility R,
|
|||
return;
|
||||
}
|
||||
|
||||
R.replace(reexports(PDR.getImplDylib(), std::move(NonCallables)));
|
||||
R.replace(reexports(PDR.getImplDylib(), std::move(NonCallables), true));
|
||||
R.replace(lazyReexports(LCTMgr, PDR.getISManager(), PDR.getImplDylib(),
|
||||
std::move(Callables)));
|
||||
}
|
||||
|
@ -166,10 +166,17 @@ CompileOnDemandLayer::PerDylibResources &
|
|||
CompileOnDemandLayer::getPerDylibResources(JITDylib &TargetD) {
|
||||
auto I = DylibResources.find(&TargetD);
|
||||
if (I == DylibResources.end()) {
|
||||
auto &ImplD =
|
||||
getExecutionSession().createJITDylib(TargetD.getName() + ".impl");
|
||||
TargetD.withSearchOrderDo([&](const JITDylibList &TargetSearchOrder) {
|
||||
ImplD.setSearchOrder(TargetSearchOrder, false);
|
||||
auto &ImplD = getExecutionSession().createJITDylib(
|
||||
TargetD.getName() + ".impl", false);
|
||||
TargetD.withSearchOrderDo([&](const JITDylibSearchList &TargetSearchOrder) {
|
||||
auto NewSearchOrder = TargetSearchOrder;
|
||||
assert(!NewSearchOrder.empty() &&
|
||||
NewSearchOrder.front().first == &TargetD &&
|
||||
NewSearchOrder.front().second == true &&
|
||||
"TargetD must be at the front of its own search order and match "
|
||||
"non-exported symbol");
|
||||
NewSearchOrder.insert(std::next(NewSearchOrder.begin()), {&ImplD, true});
|
||||
ImplD.setSearchOrder(std::move(NewSearchOrder), false);
|
||||
});
|
||||
PerDylibResources PDR(ImplD, BuildIndirectStubsManager());
|
||||
I = DylibResources.insert(std::make_pair(&TargetD, std::move(PDR))).first;
|
||||
|
|
|
@ -205,14 +205,16 @@ raw_ostream &operator<<(raw_ostream &OS, const MaterializationUnit &MU) {
|
|||
return OS << ")";
|
||||
}
|
||||
|
||||
raw_ostream &operator<<(raw_ostream &OS, const JITDylibList &JDs) {
|
||||
raw_ostream &operator<<(raw_ostream &OS, const JITDylibSearchList &JDs) {
|
||||
OS << "[";
|
||||
if (!JDs.empty()) {
|
||||
assert(JDs.front() && "JITDylibList entries must not be null");
|
||||
OS << " " << JDs.front()->getName();
|
||||
for (auto *JD : make_range(std::next(JDs.begin()), JDs.end())) {
|
||||
assert(JD && "JITDylibList entries must not be null");
|
||||
OS << ", " << JD->getName();
|
||||
assert(JDs.front().first && "JITDylibList entries must not be null");
|
||||
OS << " (\"" << JDs.front().first->getName() << "\", "
|
||||
<< (JDs.front().second ? "true" : "false") << ")";
|
||||
for (auto &KV : make_range(std::next(JDs.begin()), JDs.end())) {
|
||||
assert(KV.first && "JITDylibList entries must not be null");
|
||||
OS << ", (\"" << KV.first->getName() << "\", "
|
||||
<< (KV.second ? "true" : "false") << ")";
|
||||
}
|
||||
}
|
||||
OS << " ]";
|
||||
|
@ -526,9 +528,11 @@ AbsoluteSymbolsMaterializationUnit::extractFlags(const SymbolMap &Symbols) {
|
|||
}
|
||||
|
||||
ReExportsMaterializationUnit::ReExportsMaterializationUnit(
|
||||
JITDylib *SourceJD, SymbolAliasMap Aliases, VModuleKey K)
|
||||
JITDylib *SourceJD, bool MatchNonExported, SymbolAliasMap Aliases,
|
||||
VModuleKey K)
|
||||
: MaterializationUnit(extractFlags(Aliases), std::move(K)),
|
||||
SourceJD(SourceJD), Aliases(std::move(Aliases)) {}
|
||||
SourceJD(SourceJD), MatchNonExported(MatchNonExported),
|
||||
Aliases(std::move(Aliases)) {}
|
||||
|
||||
StringRef ReExportsMaterializationUnit::getName() const {
|
||||
return "<Reexports>";
|
||||
|
@ -556,7 +560,7 @@ void ReExportsMaterializationUnit::materialize(
|
|||
|
||||
if (!Aliases.empty()) {
|
||||
if (SourceJD)
|
||||
R.replace(reexports(*SourceJD, std::move(Aliases)));
|
||||
R.replace(reexports(*SourceJD, std::move(Aliases), MatchNonExported));
|
||||
else
|
||||
R.replace(symbolAliases(std::move(Aliases)));
|
||||
}
|
||||
|
@ -656,8 +660,9 @@ void ReExportsMaterializationUnit::materialize(
|
|||
|
||||
auto OnReady = [&ES](Error Err) { ES.reportError(std::move(Err)); };
|
||||
|
||||
ES.lookup({&SrcJD}, QuerySymbols, std::move(OnResolve), std::move(OnReady),
|
||||
std::move(RegisterDependencies), nullptr, true);
|
||||
ES.lookup(JITDylibSearchList({{&SrcJD, MatchNonExported}}), QuerySymbols,
|
||||
std::move(OnResolve), std::move(OnReady),
|
||||
std::move(RegisterDependencies));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -698,8 +703,10 @@ buildSimpleReexportsAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols) {
|
|||
}
|
||||
|
||||
ReexportsGenerator::ReexportsGenerator(JITDylib &SourceJD,
|
||||
bool MatchNonExported,
|
||||
SymbolPredicate Allow)
|
||||
: SourceJD(SourceJD), Allow(std::move(Allow)) {}
|
||||
: SourceJD(SourceJD), MatchNonExported(MatchNonExported),
|
||||
Allow(std::move(Allow)) {}
|
||||
|
||||
SymbolNameSet ReexportsGenerator::operator()(JITDylib &JD,
|
||||
const SymbolNameSet &Names) {
|
||||
|
@ -716,7 +723,7 @@ SymbolNameSet ReexportsGenerator::operator()(JITDylib &JD,
|
|||
}
|
||||
|
||||
if (!Added.empty())
|
||||
cantFail(JD.define(reexports(SourceJD, AliasMap)));
|
||||
cantFail(JD.define(reexports(SourceJD, AliasMap, MatchNonExported)));
|
||||
|
||||
return Added;
|
||||
}
|
||||
|
@ -1041,30 +1048,41 @@ void JITDylib::notifyFailed(const SymbolNameSet &FailedSymbols) {
|
|||
Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbols));
|
||||
}
|
||||
|
||||
void JITDylib::setSearchOrder(JITDylibList NewSearchOrder,
|
||||
bool SearchThisJITDylibFirst) {
|
||||
if (SearchThisJITDylibFirst && NewSearchOrder.front() != this)
|
||||
NewSearchOrder.insert(NewSearchOrder.begin(), this);
|
||||
void JITDylib::setSearchOrder(JITDylibSearchList NewSearchOrder,
|
||||
bool SearchThisJITDylibFirst,
|
||||
bool MatchNonExportedInThisDylib) {
|
||||
if (SearchThisJITDylibFirst && NewSearchOrder.front().first != this)
|
||||
NewSearchOrder.insert(NewSearchOrder.begin(),
|
||||
{this, MatchNonExportedInThisDylib});
|
||||
|
||||
ES.runSessionLocked([&]() { SearchOrder = std::move(NewSearchOrder); });
|
||||
}
|
||||
|
||||
void JITDylib::addToSearchOrder(JITDylib &JD) {
|
||||
ES.runSessionLocked([&]() { SearchOrder.push_back(&JD); });
|
||||
void JITDylib::addToSearchOrder(JITDylib &JD, bool MatchNonExported) {
|
||||
ES.runSessionLocked([&]() {
|
||||
SearchOrder.push_back({&JD, MatchNonExported});
|
||||
});
|
||||
}
|
||||
|
||||
void JITDylib::replaceInSearchOrder(JITDylib &OldJD, JITDylib &NewJD) {
|
||||
void JITDylib::replaceInSearchOrder(JITDylib &OldJD, JITDylib &NewJD,
|
||||
bool MatchNonExported) {
|
||||
ES.runSessionLocked([&]() {
|
||||
auto I = std::find(SearchOrder.begin(), SearchOrder.end(), &OldJD);
|
||||
auto I = std::find_if(SearchOrder.begin(), SearchOrder.end(),
|
||||
[&](const JITDylibSearchList::value_type &KV) {
|
||||
return KV.first == &OldJD;
|
||||
});
|
||||
|
||||
if (I != SearchOrder.end())
|
||||
*I = &NewJD;
|
||||
*I = {&NewJD, MatchNonExported};
|
||||
});
|
||||
}
|
||||
|
||||
void JITDylib::removeFromSearchOrder(JITDylib &JD) {
|
||||
ES.runSessionLocked([&]() {
|
||||
auto I = std::find(SearchOrder.begin(), SearchOrder.end(), &JD);
|
||||
auto I = std::find_if(SearchOrder.begin(), SearchOrder.end(),
|
||||
[&](const JITDylibSearchList::value_type &KV) {
|
||||
return KV.first == &JD;
|
||||
});
|
||||
if (I != SearchOrder.end())
|
||||
SearchOrder.erase(I);
|
||||
});
|
||||
|
@ -1161,18 +1179,17 @@ SymbolNameSet JITDylib::lookupFlagsImpl(SymbolFlagsMap &Flags,
|
|||
}
|
||||
|
||||
void JITDylib::lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q,
|
||||
SymbolNameSet &Unresolved,
|
||||
JITDylib *MatchNonExportedInJD, bool MatchNonExported,
|
||||
SymbolNameSet &Unresolved, bool MatchNonExported,
|
||||
MaterializationUnitList &MUs) {
|
||||
assert(Q && "Query can not be null");
|
||||
|
||||
lodgeQueryImpl(Q, Unresolved, MatchNonExportedInJD, MatchNonExported, MUs);
|
||||
lodgeQueryImpl(Q, Unresolved, MatchNonExported, MUs);
|
||||
if (DefGenerator && !Unresolved.empty()) {
|
||||
auto NewDefs = DefGenerator(*this, Unresolved);
|
||||
if (!NewDefs.empty()) {
|
||||
for (auto &D : NewDefs)
|
||||
Unresolved.erase(D);
|
||||
lodgeQueryImpl(Q, NewDefs, MatchNonExportedInJD, MatchNonExported, MUs);
|
||||
lodgeQueryImpl(Q, NewDefs, MatchNonExported, MUs);
|
||||
assert(NewDefs.empty() &&
|
||||
"All fallback defs should have been found by lookupImpl");
|
||||
}
|
||||
|
@ -1181,7 +1198,7 @@ void JITDylib::lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q,
|
|||
|
||||
void JITDylib::lodgeQueryImpl(
|
||||
std::shared_ptr<AsynchronousSymbolQuery> &Q, SymbolNameSet &Unresolved,
|
||||
JITDylib *MatchNonExportedInJD, bool MatchNonExported,
|
||||
bool MatchNonExported,
|
||||
std::vector<std::unique_ptr<MaterializationUnit>> &MUs) {
|
||||
|
||||
std::vector<SymbolStringPtr> ToRemove;
|
||||
|
@ -1191,12 +1208,9 @@ void JITDylib::lodgeQueryImpl(
|
|||
if (SymI == Symbols.end())
|
||||
continue;
|
||||
|
||||
// If this is a non-exported symbol, then check the values of
|
||||
// MatchNonExportedInJD and MatchNonExported. Skip if we should not match
|
||||
// against this symbol.
|
||||
if (!SymI->second.getFlags().isExported())
|
||||
if (!MatchNonExported && MatchNonExportedInJD != this)
|
||||
continue;
|
||||
// If this is a non exported symbol and we're skipping those then skip it.
|
||||
if (!SymI->second.getFlags().isExported() && !MatchNonExported)
|
||||
continue;
|
||||
|
||||
// If we matched against Name in JD, mark it to be removed from the Unresolved
|
||||
// set.
|
||||
|
@ -1382,8 +1396,9 @@ void JITDylib::dump(raw_ostream &OS) {
|
|||
<< "\" (ES: " << format("0x%016x", reinterpret_cast<uintptr_t>(&ES))
|
||||
<< "):\n"
|
||||
<< "Search order: [";
|
||||
for (auto *JD : SearchOrder)
|
||||
OS << " \"" << JD->getName() << "\"";
|
||||
for (auto &KV : SearchOrder)
|
||||
OS << " (\"" << KV.first->getName() << "\", "
|
||||
<< (KV.second ? "all" : "exported only") << ")";
|
||||
OS << " ]\n"
|
||||
<< "Symbol table:\n";
|
||||
|
||||
|
@ -1431,7 +1446,7 @@ void JITDylib::dump(raw_ostream &OS) {
|
|||
|
||||
JITDylib::JITDylib(ExecutionSession &ES, std::string Name)
|
||||
: ES(ES), JITDylibName(std::move(Name)) {
|
||||
SearchOrder.push_back(this);
|
||||
SearchOrder.push_back({this, true});
|
||||
}
|
||||
|
||||
Error JITDylib::defineImpl(MaterializationUnit &MU) {
|
||||
|
@ -1724,12 +1739,10 @@ Expected<SymbolMap> ExecutionSession::legacyLookup(
|
|||
#endif
|
||||
}
|
||||
|
||||
void ExecutionSession::lookup(const JITDylibList &JDs, SymbolNameSet Symbols,
|
||||
SymbolsResolvedCallback OnResolve,
|
||||
SymbolsReadyCallback OnReady,
|
||||
RegisterDependenciesFunction RegisterDependencies,
|
||||
JITDylib *MatchNonExportedInJD,
|
||||
bool MatchNonExported) {
|
||||
void ExecutionSession::lookup(
|
||||
const JITDylibSearchList &SearchOrder, SymbolNameSet Symbols,
|
||||
SymbolsResolvedCallback OnResolve, SymbolsReadyCallback OnReady,
|
||||
RegisterDependenciesFunction RegisterDependencies) {
|
||||
|
||||
// lookup can be re-entered recursively if running on a single thread. Run any
|
||||
// outstanding MUs in case this query depends on them, otherwise this lookup
|
||||
|
@ -1745,12 +1758,14 @@ void ExecutionSession::lookup(const JITDylibList &JDs, SymbolNameSet Symbols,
|
|||
bool QueryFailed = false;
|
||||
|
||||
runSessionLocked([&]() {
|
||||
for (auto *JD : JDs) {
|
||||
assert(JD && "JITDylibList entries must not be null");
|
||||
assert(!CollectedMUsMap.count(JD) &&
|
||||
for (auto &KV : SearchOrder) {
|
||||
assert(KV.first && "JITDylibList entries must not be null");
|
||||
assert(!CollectedMUsMap.count(KV.first) &&
|
||||
"JITDylibList should not contain duplicate entries");
|
||||
JD->lodgeQuery(Q, Unresolved, MatchNonExportedInJD, MatchNonExported,
|
||||
CollectedMUsMap[JD]);
|
||||
|
||||
auto &JD = *KV.first;
|
||||
auto MatchNonExported = KV.second;
|
||||
JD.lodgeQuery(Q, Unresolved, MatchNonExported, CollectedMUsMap[&JD]);
|
||||
}
|
||||
|
||||
if (Unresolved.empty()) {
|
||||
|
@ -1801,11 +1816,9 @@ void ExecutionSession::lookup(const JITDylibList &JDs, SymbolNameSet Symbols,
|
|||
runOutstandingMUs();
|
||||
}
|
||||
|
||||
Expected<SymbolMap>
|
||||
ExecutionSession::lookup(const JITDylibList &JDs, const SymbolNameSet &Symbols,
|
||||
RegisterDependenciesFunction RegisterDependencies,
|
||||
bool WaitUntilReady, JITDylib *MatchNonExportedInJD,
|
||||
bool MatchNonExported) {
|
||||
Expected<SymbolMap> ExecutionSession::lookup(
|
||||
const JITDylibSearchList &SearchOrder, const SymbolNameSet &Symbols,
|
||||
RegisterDependenciesFunction RegisterDependencies, bool WaitUntilReady) {
|
||||
#if LLVM_ENABLE_THREADS
|
||||
// In the threaded case we use promises to return the results.
|
||||
std::promise<SymbolMap> PromisedResult;
|
||||
|
@ -1872,8 +1885,7 @@ ExecutionSession::lookup(const JITDylibList &JDs, const SymbolNameSet &Symbols,
|
|||
#endif
|
||||
|
||||
// Perform the asynchronous lookup.
|
||||
lookup(JDs, Symbols, OnResolve, OnReady, RegisterDependencies,
|
||||
MatchNonExportedInJD, MatchNonExported);
|
||||
lookup(SearchOrder, Symbols, OnResolve, OnReady, RegisterDependencies);
|
||||
|
||||
#if LLVM_ENABLE_THREADS
|
||||
auto ResultFuture = PromisedResult.get_future();
|
||||
|
@ -1916,14 +1928,13 @@ ExecutionSession::lookup(const JITDylibList &JDs, const SymbolNameSet &Symbols,
|
|||
#endif
|
||||
}
|
||||
|
||||
/// Look up a symbol by searching a list of JDs.
|
||||
Expected<JITEvaluatedSymbol> ExecutionSession::lookup(const JITDylibList &JDs,
|
||||
SymbolStringPtr Name,
|
||||
bool MatchNonExported) {
|
||||
Expected<JITEvaluatedSymbol>
|
||||
ExecutionSession::lookup(const JITDylibSearchList &SearchOrder,
|
||||
SymbolStringPtr Name) {
|
||||
SymbolNameSet Names({Name});
|
||||
|
||||
if (auto ResultMap = lookup(JDs, std::move(Names), NoDependenciesToRegister,
|
||||
true, nullptr, MatchNonExported)) {
|
||||
if (auto ResultMap = lookup(SearchOrder, std::move(Names),
|
||||
NoDependenciesToRegister, true)) {
|
||||
assert(ResultMap->size() == 1 && "Unexpected number of results");
|
||||
assert(ResultMap->count(Name) && "Missing result for symbol");
|
||||
return std::move(ResultMap->begin()->second);
|
||||
|
@ -1931,10 +1942,21 @@ Expected<JITEvaluatedSymbol> ExecutionSession::lookup(const JITDylibList &JDs,
|
|||
return ResultMap.takeError();
|
||||
}
|
||||
|
||||
Expected<JITEvaluatedSymbol> ExecutionSession::lookup(const JITDylibList &JDs,
|
||||
StringRef Name,
|
||||
bool MatchNonExported) {
|
||||
return lookup(JDs, intern(Name), MatchNonExported);
|
||||
Expected<JITEvaluatedSymbol>
|
||||
ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder,
|
||||
SymbolStringPtr Name) {
|
||||
SymbolNameSet Names({Name});
|
||||
|
||||
JITDylibSearchList FullSearchOrder(SearchOrder.size());
|
||||
for (auto *JD : SearchOrder)
|
||||
FullSearchOrder.push_back({JD, false});
|
||||
|
||||
return lookup(FullSearchOrder, Name);
|
||||
}
|
||||
|
||||
Expected<JITEvaluatedSymbol>
|
||||
ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, StringRef Name) {
|
||||
return lookup(SearchOrder, intern(Name));
|
||||
}
|
||||
|
||||
void ExecutionSession::dump(raw_ostream &OS) {
|
||||
|
|
|
@ -130,8 +130,8 @@ Error CtorDtorRunner::run() {
|
|||
|
||||
auto &ES = JD.getExecutionSession();
|
||||
if (auto CtorDtorMap =
|
||||
ES.lookup({&JD}, std::move(Names), NoDependenciesToRegister, true,
|
||||
nullptr, true)) {
|
||||
ES.lookup(JITDylibSearchList({{&JD, true}}), std::move(Names),
|
||||
NoDependenciesToRegister, true)) {
|
||||
for (auto &KV : CtorDtorsByPriority) {
|
||||
for (auto &Name : KV.second) {
|
||||
assert(CtorDtorMap->count(Name) && "No entry for Name");
|
||||
|
|
|
@ -101,7 +101,7 @@ JITTargetAddress JITCompileCallbackManager::executeCompileCallback(
|
|||
Name = I->second;
|
||||
}
|
||||
|
||||
if (auto Sym = ES.lookup({&CallbacksJD}, Name, true))
|
||||
if (auto Sym = ES.lookup(JITDylibSearchList({{&CallbacksJD, true}}), Name))
|
||||
return Sym->getAddress();
|
||||
else {
|
||||
llvm::dbgs() << "Didn't find callback.\n";
|
||||
|
|
|
@ -76,7 +76,7 @@ Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) {
|
|||
|
||||
Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD,
|
||||
StringRef Name) {
|
||||
return ES->lookup({&JD}, ES->intern(Name));
|
||||
return ES->lookup(JITDylibSearchList({{&JD, true}}), ES->intern(Name));
|
||||
}
|
||||
|
||||
LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES,
|
||||
|
@ -144,13 +144,13 @@ void LLJIT::recordCtorDtors(Module &M) {
|
|||
}
|
||||
|
||||
Expected<std::unique_ptr<LLLazyJIT>>
|
||||
LLLazyJIT::Create(JITTargetMachineBuilder JTMB, DataLayout DL,
|
||||
unsigned NumCompileThreads) {
|
||||
LLLazyJIT::Create(JITTargetMachineBuilder JTMB, DataLayout DL,
|
||||
JITTargetAddress ErrorAddr, unsigned NumCompileThreads) {
|
||||
auto ES = llvm::make_unique<ExecutionSession>();
|
||||
|
||||
const Triple &TT = JTMB.getTargetTriple();
|
||||
|
||||
auto LCTMgr = createLocalLazyCallThroughManager(TT, *ES, 0);
|
||||
auto LCTMgr = createLocalLazyCallThroughManager(TT, *ES, ErrorAddr);
|
||||
if (!LCTMgr)
|
||||
return LCTMgr.takeError();
|
||||
|
||||
|
|
|
@ -52,8 +52,8 @@ LazyCallThroughManager::callThroughToSymbol(JITTargetAddress TrampolineAddr) {
|
|||
SymbolName = I->second.second;
|
||||
}
|
||||
|
||||
auto LookupResult = ES.lookup({SourceJD}, {SymbolName},
|
||||
NoDependenciesToRegister, true, nullptr, true);
|
||||
auto LookupResult = ES.lookup(JITDylibSearchList({{SourceJD, true}}),
|
||||
{SymbolName}, NoDependenciesToRegister, true);
|
||||
|
||||
if (!LookupResult) {
|
||||
ES.reportError(LookupResult.takeError());
|
||||
|
|
|
@ -50,10 +50,11 @@ public:
|
|||
MR.addDependenciesForAll(Deps);
|
||||
};
|
||||
|
||||
MR.getTargetJITDylib().withSearchOrderDo([&](const JITDylibList &JDs) {
|
||||
ES.lookup(JDs, InternedSymbols, OnResolvedWithUnwrap, OnReady,
|
||||
RegisterDependencies, &MR.getTargetJITDylib());
|
||||
});
|
||||
JITDylibSearchList SearchOrder;
|
||||
MR.getTargetJITDylib().withSearchOrderDo(
|
||||
[&](const JITDylibSearchList &JDs) { SearchOrder = JDs; });
|
||||
ES.lookup(SearchOrder, InternedSymbols, OnResolvedWithUnwrap, OnReady,
|
||||
RegisterDependencies);
|
||||
}
|
||||
|
||||
Expected<LookupSet> getResponsibilitySet(const LookupSet &Symbols) {
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
@bar = hidden global i32 0
|
||||
|
||||
define hidden i32 @foo() {
|
||||
entry:
|
||||
ret i32 0
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
; RUN: lli -jit-kind=orc-lazy -extra-module %p/Inputs/hidden-definitions.ll %s
|
||||
; RUN: not lli -jit-kind=orc-lazy -jd libFoo -extra-module %p/Inputs/hidden-definitions.ll %s
|
||||
;
|
||||
; Check that hidden symbols in another module are visible when the module is
|
||||
; added to the same JITDylib, and not visible if it is added to a different
|
||||
; JITDylib.
|
||||
|
||||
@bar = external global i32
|
||||
declare i32 @foo()
|
||||
|
||||
define i32 @main(i32 %argc, i8** nocapture readnone %argv) {
|
||||
entry:
|
||||
%0 = call i32() @foo()
|
||||
%1 = load i32, i32* @bar
|
||||
%2 = add i32 %0, %1
|
||||
ret i32 %2
|
||||
}
|
|
@ -115,6 +115,11 @@ namespace {
|
|||
"rather than individual functions"),
|
||||
cl::init(false));
|
||||
|
||||
cl::list<std::string>
|
||||
JITDylibs("jd",
|
||||
cl::desc("Specifies the JITDylib to be used for any subsequent "
|
||||
"-extra-module arguments."));
|
||||
|
||||
// The MCJIT supports building for a target address space separate from
|
||||
// the JIT compilation process. Use a forked process and a copying
|
||||
// memory manager with IPC to execute using this functionality.
|
||||
|
@ -749,6 +754,8 @@ static orc::IRTransformLayer::TransformFunction createDebugDumper() {
|
|||
llvm_unreachable("Unknown DumpKind");
|
||||
}
|
||||
|
||||
static void exitOnLazyCallThroughFailure() { exit(1); }
|
||||
|
||||
int runOrcLazyJIT(const char *ProgName) {
|
||||
// Start setting up the JIT environment.
|
||||
|
||||
|
@ -778,7 +785,11 @@ int runOrcLazyJIT(const char *ProgName) {
|
|||
: None);
|
||||
|
||||
DataLayout DL = ExitOnErr(JTMB.getDefaultDataLayoutForTarget());
|
||||
auto J = ExitOnErr(orc::LLLazyJIT::Create(std::move(JTMB), DL, LazyJITCompileThreads));
|
||||
|
||||
auto J = ExitOnErr(orc::LLLazyJIT::Create(
|
||||
std::move(JTMB), DL,
|
||||
pointerToJITTargetAddress(exitOnLazyCallThroughFailure),
|
||||
LazyJITCompileThreads));
|
||||
|
||||
if (PerModuleLazy)
|
||||
J->setPartitionFunction(orc::CompileOnDemandLayer::compileWholeModule);
|
||||
|
@ -803,13 +814,32 @@ int runOrcLazyJIT(const char *ProgName) {
|
|||
// Add the main module.
|
||||
ExitOnErr(J->addLazyIRModule(std::move(MainModule)));
|
||||
|
||||
// Add any extra modules.
|
||||
for (auto &ModulePath : ExtraModules) {
|
||||
auto M = parseIRFile(ModulePath, Err, *TSCtx.getContext());
|
||||
if (!M)
|
||||
reportError(Err, ProgName);
|
||||
// Create JITDylibs and add any extra modules.
|
||||
{
|
||||
// Create JITDylibs, keep a map from argument index to dylib. We will use
|
||||
// -extra-module argument indexes to determine what dylib to use for each
|
||||
// -extra-module.
|
||||
std::map<unsigned, orc::JITDylib *> IdxToDylib;
|
||||
IdxToDylib[0] = &J->getMainJITDylib();
|
||||
for (auto JDItr = JITDylibs.begin(), JDEnd = JITDylibs.end();
|
||||
JDItr != JDEnd; ++JDItr) {
|
||||
IdxToDylib[JITDylibs.getPosition(JDItr - JITDylibs.begin())] =
|
||||
&J->createJITDylib(*JDItr);
|
||||
}
|
||||
|
||||
ExitOnErr(J->addLazyIRModule(orc::ThreadSafeModule(std::move(M), TSCtx)));
|
||||
for (auto EMItr = ExtraModules.begin(), EMEnd = ExtraModules.end();
|
||||
EMItr != EMEnd; ++EMItr) {
|
||||
auto M = parseIRFile(*EMItr, Err, *TSCtx.getContext());
|
||||
if (!M)
|
||||
reportError(Err, ProgName);
|
||||
|
||||
auto EMIdx = ExtraModules.getPosition(EMItr - ExtraModules.begin());
|
||||
assert(EMIdx != 0 && "ExtraModule should have index > 0");
|
||||
auto JDItr = std::prev(IdxToDylib.lower_bound(EMIdx));
|
||||
auto &JD = *JDItr->second;
|
||||
ExitOnErr(
|
||||
J->addLazyIRModule(JD, orc::ThreadSafeModule(std::move(M), TSCtx)));
|
||||
}
|
||||
}
|
||||
|
||||
// Add the objects.
|
||||
|
@ -837,6 +867,8 @@ int runOrcLazyJIT(const char *ProgName) {
|
|||
AltEntryThreads.push_back(std::thread([EntryPoint]() { EntryPoint(); }));
|
||||
}
|
||||
|
||||
J->getExecutionSession().dump(llvm::dbgs());
|
||||
|
||||
// Run main.
|
||||
auto MainSym = ExitOnErr(J->lookup("main"));
|
||||
typedef int (*MainFnPtr)(int, const char *[]);
|
||||
|
|
|
@ -48,7 +48,8 @@ TEST_F(CoreAPIsStandardTest, BasicSuccessfulLookup) {
|
|||
FooMR = std::make_shared<MaterializationResponsibility>(std::move(R));
|
||||
})));
|
||||
|
||||
ES.lookup({&JD}, {Foo}, OnResolution, OnReady, NoDependenciesToRegister);
|
||||
ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, OnResolution, OnReady,
|
||||
NoDependenciesToRegister);
|
||||
|
||||
EXPECT_FALSE(OnResolutionRun) << "Should not have been resolved yet";
|
||||
EXPECT_FALSE(OnReadyRun) << "Should not have been marked ready yet";
|
||||
|
@ -101,7 +102,8 @@ TEST_F(CoreAPIsStandardTest, EmptyLookup) {
|
|||
OnReadyRun = true;
|
||||
};
|
||||
|
||||
ES.lookup({&JD}, {}, OnResolution, OnReady, NoDependenciesToRegister);
|
||||
ES.lookup(JITDylibSearchList({{&JD, false}}), {}, OnResolution, OnReady,
|
||||
NoDependenciesToRegister);
|
||||
|
||||
EXPECT_TRUE(OnResolvedRun) << "OnResolved was not run for empty query";
|
||||
EXPECT_TRUE(OnReadyRun) << "OnReady was not run for empty query";
|
||||
|
@ -148,7 +150,7 @@ TEST_F(CoreAPIsStandardTest, RemoveSymbolsTest) {
|
|||
|
||||
bool OnResolvedRun = false;
|
||||
bool OnReadyRun = false;
|
||||
ES.lookup({&JD}, {Foo, Baz},
|
||||
ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo, Baz},
|
||||
[&](Expected<SymbolMap> Result) {
|
||||
EXPECT_TRUE(!!Result) << "OnResolved failed unexpectedly";
|
||||
consumeError(Result.takeError());
|
||||
|
@ -229,7 +231,9 @@ TEST_F(CoreAPIsStandardTest, LookupWithHiddenSymbols) {
|
|||
auto &JD2 = ES.createJITDylib("JD2");
|
||||
cantFail(JD2.define(absoluteSymbols({{Bar, QuxSym}})));
|
||||
|
||||
auto Result = cantFail(ES.lookup({&JD, &JD2}, {Foo, Bar}));
|
||||
/// Try a blocking lookup.
|
||||
auto Result = cantFail(
|
||||
ES.lookup(JITDylibSearchList({{&JD, false}, {&JD2, false}}), {Foo, Bar}));
|
||||
|
||||
EXPECT_EQ(Result.size(), 2U) << "Unexpected number of results";
|
||||
EXPECT_EQ(Result.count(Foo), 1U) << "Missing result for \"Foo\"";
|
||||
|
@ -275,7 +279,7 @@ TEST_F(CoreAPIsStandardTest, TestBasicAliases) {
|
|||
{Qux, {Bar, JITSymbolFlags::Weak}}})));
|
||||
cantFail(JD.define(absoluteSymbols({{Qux, QuxSym}})));
|
||||
|
||||
auto Result = ES.lookup({&JD}, {Baz, Qux});
|
||||
auto Result = ES.lookup(JITDylibSearchList({{&JD, false}}), {Baz, Qux});
|
||||
EXPECT_TRUE(!!Result) << "Unexpected lookup failure";
|
||||
EXPECT_EQ(Result->count(Baz), 1U) << "No result for \"baz\"";
|
||||
EXPECT_EQ(Result->count(Qux), 1U) << "No result for \"qux\"";
|
||||
|
@ -290,7 +294,7 @@ TEST_F(CoreAPIsStandardTest, TestChainedAliases) {
|
|||
cantFail(JD.define(symbolAliases(
|
||||
{{Baz, {Bar, BazSym.getFlags()}}, {Bar, {Foo, BarSym.getFlags()}}})));
|
||||
|
||||
auto Result = ES.lookup({&JD}, {Bar, Baz});
|
||||
auto Result = ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar, Baz});
|
||||
EXPECT_TRUE(!!Result) << "Unexpected lookup failure";
|
||||
EXPECT_EQ(Result->count(Bar), 1U) << "No result for \"bar\"";
|
||||
EXPECT_EQ(Result->count(Baz), 1U) << "No result for \"baz\"";
|
||||
|
@ -309,7 +313,7 @@ TEST_F(CoreAPIsStandardTest, TestBasicReExports) {
|
|||
|
||||
cantFail(JD2.define(reexports(JD, {{Bar, {Foo, BarSym.getFlags()}}})));
|
||||
|
||||
auto Result = cantFail(ES.lookup({&JD2}, Bar));
|
||||
auto Result = cantFail(ES.lookup(JITDylibSearchList({{&JD2, false}}), Bar));
|
||||
EXPECT_EQ(Result.getAddress(), FooSym.getAddress())
|
||||
<< "Re-export Bar for symbol Foo should match FooSym's address";
|
||||
}
|
||||
|
@ -335,7 +339,7 @@ TEST_F(CoreAPIsStandardTest, TestThatReExportsDontUnnecessarilyMaterialize) {
|
|||
cantFail(JD2.define(reexports(
|
||||
JD, {{Baz, {Foo, BazSym.getFlags()}}, {Qux, {Bar, QuxSym.getFlags()}}})));
|
||||
|
||||
auto Result = cantFail(ES.lookup({&JD2}, Baz));
|
||||
auto Result = cantFail(ES.lookup(JITDylibSearchList({{&JD2, false}}), Baz));
|
||||
EXPECT_EQ(Result.getAddress(), FooSym.getAddress())
|
||||
<< "Re-export Baz for symbol Foo should match FooSym's address";
|
||||
|
||||
|
@ -350,13 +354,13 @@ TEST_F(CoreAPIsStandardTest, TestReexportsGenerator) {
|
|||
|
||||
auto Filter = [this](SymbolStringPtr Name) { return Name != Bar; };
|
||||
|
||||
JD.setGenerator(ReexportsGenerator(JD2, Filter));
|
||||
JD.setGenerator(ReexportsGenerator(JD2, false, Filter));
|
||||
|
||||
auto Flags = JD.lookupFlags({Foo, Bar, Baz});
|
||||
EXPECT_EQ(Flags.size(), 1U) << "Unexpected number of results";
|
||||
EXPECT_EQ(Flags[Foo], FooSym.getFlags()) << "Unexpected flags for Foo";
|
||||
|
||||
auto Result = cantFail(ES.lookup({&JD}, Foo));
|
||||
auto Result = cantFail(ES.lookup(JITDylibSearchList({{&JD, false}}), Foo));
|
||||
|
||||
EXPECT_EQ(Result.getAddress(), FooSym.getAddress())
|
||||
<< "Incorrect reexported symbol address";
|
||||
|
@ -377,8 +381,8 @@ TEST_F(CoreAPIsStandardTest, TestTrivialCircularDependency) {
|
|||
FooReady = true;
|
||||
};
|
||||
|
||||
ES.lookup({&JD}, {Foo}, std::move(OnResolution), std::move(OnReady),
|
||||
NoDependenciesToRegister);
|
||||
ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, std::move(OnResolution),
|
||||
std::move(OnReady), NoDependenciesToRegister);
|
||||
|
||||
FooR->resolve({{Foo, FooSym}});
|
||||
FooR->emit();
|
||||
|
@ -434,7 +438,8 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneJITDylib) {
|
|||
|
||||
// Issue a lookup for Foo. Use NoDependenciesToRegister: We're going to add
|
||||
// the dependencies manually below.
|
||||
ES.lookup({&JD}, {Foo}, std::move(OnFooResolution), std::move(OnFooReady),
|
||||
ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo},
|
||||
std::move(OnFooResolution), std::move(OnFooReady),
|
||||
NoDependenciesToRegister);
|
||||
|
||||
bool BarResolved = false;
|
||||
|
@ -449,7 +454,8 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneJITDylib) {
|
|||
BarReady = true;
|
||||
};
|
||||
|
||||
ES.lookup({&JD}, {Bar}, std::move(OnBarResolution), std::move(OnBarReady),
|
||||
ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar},
|
||||
std::move(OnBarResolution), std::move(OnBarReady),
|
||||
NoDependenciesToRegister);
|
||||
|
||||
bool BazResolved = false;
|
||||
|
@ -465,7 +471,8 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneJITDylib) {
|
|||
BazReady = true;
|
||||
};
|
||||
|
||||
ES.lookup({&JD}, {Baz}, std::move(OnBazResolution), std::move(OnBazReady),
|
||||
ES.lookup(JITDylibSearchList({{&JD, false}}), {Baz},
|
||||
std::move(OnBazResolution), std::move(OnBazReady),
|
||||
NoDependenciesToRegister);
|
||||
|
||||
// Add a circular dependency: Foo -> Bar, Bar -> Baz, Baz -> Foo.
|
||||
|
@ -588,8 +595,8 @@ TEST_F(CoreAPIsStandardTest, AddAndMaterializeLazySymbol) {
|
|||
OnReadyRun = true;
|
||||
};
|
||||
|
||||
ES.lookup({&JD}, Names, std::move(OnResolution), std::move(OnReady),
|
||||
NoDependenciesToRegister);
|
||||
ES.lookup(JITDylibSearchList({{&JD, false}}), Names, std::move(OnResolution),
|
||||
std::move(OnReady), NoDependenciesToRegister);
|
||||
|
||||
EXPECT_TRUE(FooMaterialized) << "Foo was not materialized";
|
||||
EXPECT_TRUE(BarDiscarded) << "Bar was not discarded";
|
||||
|
@ -637,8 +644,8 @@ TEST_F(CoreAPIsStandardTest, TestBasicWeakSymbolMaterialization) {
|
|||
OnReadyRun = true;
|
||||
};
|
||||
|
||||
ES.lookup({&JD}, {Bar}, std::move(OnResolution), std::move(OnReady),
|
||||
NoDependenciesToRegister);
|
||||
ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar}, std::move(OnResolution),
|
||||
std::move(OnReady), NoDependenciesToRegister);
|
||||
|
||||
EXPECT_TRUE(OnResolvedRun) << "OnResolved not run";
|
||||
EXPECT_TRUE(OnReadyRun) << "OnReady not run";
|
||||
|
@ -666,13 +673,13 @@ TEST_F(CoreAPIsStandardTest, DefineMaterializingSymbol) {
|
|||
});
|
||||
|
||||
cantFail(JD.define(MU));
|
||||
cantFail(ES.lookup({&JD}, Foo));
|
||||
cantFail(ES.lookup(JITDylibSearchList({{&JD, false}}), Foo));
|
||||
|
||||
// Assert that materialization is complete by now.
|
||||
ExpectNoMoreMaterialization = true;
|
||||
|
||||
// Look up bar to verify that no further materialization happens.
|
||||
auto BarResult = cantFail(ES.lookup({&JD}, Bar));
|
||||
auto BarResult = cantFail(ES.lookup(JITDylibSearchList({{&JD, false}}), Bar));
|
||||
EXPECT_EQ(BarResult.getAddress(), BarSym.getAddress())
|
||||
<< "Expected Bar == BarSym";
|
||||
}
|
||||
|
@ -685,7 +692,8 @@ TEST_F(CoreAPIsStandardTest, GeneratorTest) {
|
|||
return SymbolNameSet({Bar});
|
||||
});
|
||||
|
||||
auto Result = cantFail(ES.lookup({&JD}, {Foo, Bar}));
|
||||
auto Result =
|
||||
cantFail(ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo, Bar}));
|
||||
|
||||
EXPECT_EQ(Result.count(Bar), 1U) << "Expected to find fallback def for 'bar'";
|
||||
EXPECT_EQ(Result[Bar].getAddress(), BarSym.getAddress())
|
||||
|
@ -701,7 +709,7 @@ TEST_F(CoreAPIsStandardTest, FailResolution) {
|
|||
cantFail(JD.define(MU));
|
||||
|
||||
SymbolNameSet Names({Foo, Bar});
|
||||
auto Result = ES.lookup({&JD}, Names);
|
||||
auto Result = ES.lookup(JITDylibSearchList({{&JD, false}}), Names);
|
||||
|
||||
EXPECT_FALSE(!!Result) << "Expected failure";
|
||||
if (!Result) {
|
||||
|
@ -733,7 +741,8 @@ TEST_F(CoreAPIsStandardTest, TestLookupWithUnthreadedMaterialization) {
|
|||
|
||||
cantFail(JD.define(MU));
|
||||
|
||||
auto FooLookupResult = cantFail(ES.lookup({&JD}, Foo));
|
||||
auto FooLookupResult =
|
||||
cantFail(ES.lookup(JITDylibSearchList({{&JD, false}}), Foo));
|
||||
|
||||
EXPECT_EQ(FooLookupResult.getAddress(), FooSym.getAddress())
|
||||
<< "lookup returned an incorrect address";
|
||||
|
@ -754,7 +763,8 @@ TEST_F(CoreAPIsStandardTest, TestLookupWithThreadedMaterialization) {
|
|||
|
||||
cantFail(JD.define(absoluteSymbols({{Foo, FooSym}})));
|
||||
|
||||
auto FooLookupResult = cantFail(ES.lookup({&JD}, Foo));
|
||||
auto FooLookupResult =
|
||||
cantFail(ES.lookup(JITDylibSearchList({{&JD, false}}), Foo));
|
||||
|
||||
EXPECT_EQ(FooLookupResult.getAddress(), FooSym.getAddress())
|
||||
<< "lookup returned an incorrect address";
|
||||
|
@ -802,14 +812,16 @@ TEST_F(CoreAPIsStandardTest, TestGetRequestedSymbolsAndReplace) {
|
|||
EXPECT_FALSE(FooMaterialized) << "Foo should not be materialized yet";
|
||||
EXPECT_FALSE(BarMaterialized) << "Bar should not be materialized yet";
|
||||
|
||||
auto FooSymResult = cantFail(ES.lookup({&JD}, Foo));
|
||||
auto FooSymResult =
|
||||
cantFail(ES.lookup(JITDylibSearchList({{&JD, false}}), Foo));
|
||||
EXPECT_EQ(FooSymResult.getAddress(), FooSym.getAddress())
|
||||
<< "Address mismatch for Foo";
|
||||
|
||||
EXPECT_TRUE(FooMaterialized) << "Foo should be materialized now";
|
||||
EXPECT_FALSE(BarMaterialized) << "Bar still should not be materialized";
|
||||
|
||||
auto BarSymResult = cantFail(ES.lookup({&JD}, Bar));
|
||||
auto BarSymResult =
|
||||
cantFail(ES.lookup(JITDylibSearchList({{&JD, false}}), Bar));
|
||||
EXPECT_EQ(BarSymResult.getAddress(), BarSym.getAddress())
|
||||
<< "Address mismatch for Bar";
|
||||
EXPECT_TRUE(BarMaterialized) << "Bar should be materialized now";
|
||||
|
@ -829,7 +841,7 @@ TEST_F(CoreAPIsStandardTest, TestMaterializationResponsibilityDelegation) {
|
|||
|
||||
cantFail(JD.define(MU));
|
||||
|
||||
auto Result = ES.lookup({&JD}, {Foo, Bar});
|
||||
auto Result = ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo, Bar});
|
||||
|
||||
EXPECT_TRUE(!!Result) << "Result should be a success value";
|
||||
EXPECT_EQ(Result->count(Foo), 1U) << "\"Foo\" entry missing";
|
||||
|
@ -861,8 +873,8 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) {
|
|||
|
||||
auto OnReady = [](Error Err) { cantFail(std::move(Err)); };
|
||||
|
||||
ES.lookup({&JD}, {Foo}, std::move(OnResolution), std::move(OnReady),
|
||||
NoDependenciesToRegister);
|
||||
ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, std::move(OnResolution),
|
||||
std::move(OnReady), NoDependenciesToRegister);
|
||||
|
||||
auto MU2 = llvm::make_unique<SimpleMaterializationUnit>(
|
||||
SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}),
|
||||
|
|
|
@ -66,8 +66,8 @@ static bool testSetProcessAllSections(std::unique_ptr<MemoryBuffer> Obj,
|
|||
|
||||
ObjLayer.setProcessAllSections(ProcessAllSections);
|
||||
cantFail(ObjLayer.add(JD, std::move(Obj), ES.allocateVModule()));
|
||||
ES.lookup({&JD}, {Foo}, OnResolveDoNothing, OnReadyDoNothing,
|
||||
NoDependenciesToRegister);
|
||||
ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, OnResolveDoNothing,
|
||||
OnReadyDoNothing, NoDependenciesToRegister);
|
||||
return DebugSectionSeen;
|
||||
}
|
||||
|
||||
|
@ -157,7 +157,8 @@ TEST(RTDyldObjectLinkingLayerTest, TestOverrideObjectFlags) {
|
|||
ObjLayer.setOverrideObjectFlagsWithResponsibilityFlags(true);
|
||||
|
||||
cantFail(CompileLayer.add(JD, std::move(M), ES.allocateVModule()));
|
||||
ES.lookup({&JD}, {Foo}, [](Expected<SymbolMap> R) { cantFail(std::move(R)); },
|
||||
ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo},
|
||||
[](Expected<SymbolMap> R) { cantFail(std::move(R)); },
|
||||
[](Error Err) { cantFail(std::move(Err)); },
|
||||
NoDependenciesToRegister);
|
||||
}
|
||||
|
@ -219,7 +220,8 @@ TEST(RTDyldObjectLinkingLayerTest, TestAutoClaimResponsibilityForSymbols) {
|
|||
ObjLayer.setAutoClaimResponsibilityForObjectSymbols(true);
|
||||
|
||||
cantFail(CompileLayer.add(JD, std::move(M), ES.allocateVModule()));
|
||||
ES.lookup({&JD}, {Foo}, [](Expected<SymbolMap> R) { cantFail(std::move(R)); },
|
||||
ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo},
|
||||
[](Expected<SymbolMap> R) { cantFail(std::move(R)); },
|
||||
[](Error Err) { cantFail(std::move(Err)); },
|
||||
NoDependenciesToRegister);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue