forked from OSchip/llvm-project
[ORC] Reapply r342939 with a fix for MSVC's promise/future restrictions.
llvm-svn: 343012
This commit is contained in:
parent
721da4bd87
commit
adde5ba4b2
|
@ -333,6 +333,7 @@ class JITSymbolResolver {
|
|||
public:
|
||||
using LookupSet = std::set<StringRef>;
|
||||
using LookupResult = std::map<StringRef, JITEvaluatedSymbol>;
|
||||
using OnResolvedFunction = std::function<void(Expected<LookupResult>)>;
|
||||
|
||||
virtual ~JITSymbolResolver() = default;
|
||||
|
||||
|
@ -341,7 +342,8 @@ public:
|
|||
///
|
||||
/// This method will return an error if any of the given symbols can not be
|
||||
/// resolved, or if the resolution process itself triggers an error.
|
||||
virtual Expected<LookupResult> lookup(const LookupSet &Symbols) = 0;
|
||||
virtual void lookup(const LookupSet &Symbols,
|
||||
OnResolvedFunction OnResolved) = 0;
|
||||
|
||||
/// Returns the subset of the given symbols that should be materialized by
|
||||
/// the caller. Only weak/common symbols should be looked up, as strong
|
||||
|
@ -359,7 +361,7 @@ public:
|
|||
/// Performs lookup by, for each symbol, first calling
|
||||
/// findSymbolInLogicalDylib and if that fails calling
|
||||
/// findSymbol.
|
||||
Expected<LookupResult> lookup(const LookupSet &Symbols) final;
|
||||
void lookup(const LookupSet &Symbols, OnResolvedFunction OnResolved) final;
|
||||
|
||||
/// Performs flags lookup by calling findSymbolInLogicalDylib and
|
||||
/// returning the flags value for that symbol.
|
||||
|
|
|
@ -376,6 +376,7 @@ private:
|
|||
class AsynchronousSymbolQuery {
|
||||
friend class ExecutionSession;
|
||||
friend class JITDylib;
|
||||
friend class JITSymbolResolverAdapter;
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -90,12 +90,13 @@ createSymbolResolver(GetResponsibilitySetFn &&GetResponsibilitySet,
|
|||
std::forward<LookupFn>(Lookup));
|
||||
}
|
||||
|
||||
/// Legacy adapter. Remove once we kill off the old ORC layers.
|
||||
class JITSymbolResolverAdapter : public JITSymbolResolver {
|
||||
public:
|
||||
JITSymbolResolverAdapter(ExecutionSession &ES, SymbolResolver &R,
|
||||
MaterializationResponsibility *MR);
|
||||
Expected<LookupSet> getResponsibilitySet(const LookupSet &Symbols) override;
|
||||
Expected<LookupResult> lookup(const LookupSet &Symbols) override;
|
||||
void lookup(const LookupSet &Symbols, OnResolvedFunction OnResolved) override;
|
||||
|
||||
private:
|
||||
ExecutionSession &ES;
|
||||
|
|
|
@ -18,34 +18,34 @@ JITSymbolResolverAdapter::JITSymbolResolverAdapter(
|
|||
ExecutionSession &ES, SymbolResolver &R, MaterializationResponsibility *MR)
|
||||
: ES(ES), R(R), MR(MR) {}
|
||||
|
||||
Expected<JITSymbolResolverAdapter::LookupResult>
|
||||
JITSymbolResolverAdapter::lookup(const LookupSet &Symbols) {
|
||||
void JITSymbolResolverAdapter::lookup(const LookupSet &Symbols,
|
||||
OnResolvedFunction OnResolved) {
|
||||
SymbolNameSet InternedSymbols;
|
||||
for (auto &S : Symbols)
|
||||
InternedSymbols.insert(ES.getSymbolStringPool().intern(S));
|
||||
|
||||
auto LookupFn = [&, this](std::shared_ptr<AsynchronousSymbolQuery> Q,
|
||||
SymbolNameSet Unresolved) {
|
||||
return R.lookup(std::move(Q), std::move(Unresolved));
|
||||
auto OnResolvedWithUnwrap = [OnResolved](Expected<SymbolMap> InternedResult) {
|
||||
if (!InternedResult) {
|
||||
OnResolved(InternedResult.takeError());
|
||||
return;
|
||||
}
|
||||
|
||||
LookupResult Result;
|
||||
for (auto &KV : *InternedResult)
|
||||
Result[*KV.first] = std::move(KV.second);
|
||||
OnResolved(Result);
|
||||
};
|
||||
|
||||
auto RegisterDependencies = [&](const SymbolDependenceMap &Deps) {
|
||||
auto Q = std::make_shared<AsynchronousSymbolQuery>(
|
||||
InternedSymbols, OnResolvedWithUnwrap,
|
||||
[this](Error Err) { ES.reportError(std::move(Err)); });
|
||||
|
||||
auto Unresolved = R.lookup(Q, InternedSymbols);
|
||||
if (Unresolved.empty()) {
|
||||
if (MR)
|
||||
MR->addDependenciesForAll(Deps);
|
||||
};
|
||||
|
||||
auto InternedResult =
|
||||
ES.legacyLookup(std::move(LookupFn), std::move(InternedSymbols),
|
||||
false, RegisterDependencies);
|
||||
|
||||
if (!InternedResult)
|
||||
return InternedResult.takeError();
|
||||
|
||||
JITSymbolResolver::LookupResult Result;
|
||||
for (auto &KV : *InternedResult)
|
||||
Result[*KV.first] = KV.second;
|
||||
|
||||
return Result;
|
||||
MR->addDependenciesForAll(Q->QueryRegistrations);
|
||||
} else
|
||||
ES.legacyFailQuery(*Q, make_error<SymbolsNotFound>(std::move(Unresolved)));
|
||||
}
|
||||
|
||||
Expected<JITSymbolResolverAdapter::LookupSet>
|
||||
|
|
|
@ -18,30 +18,42 @@ class JITDylibSearchOrderResolver : public JITSymbolResolver {
|
|||
public:
|
||||
JITDylibSearchOrderResolver(MaterializationResponsibility &MR) : MR(MR) {}
|
||||
|
||||
Expected<LookupResult> lookup(const LookupSet &Symbols) {
|
||||
void lookup(const LookupSet &Symbols, OnResolvedFunction OnResolved) {
|
||||
auto &ES = MR.getTargetJITDylib().getExecutionSession();
|
||||
SymbolNameSet InternedSymbols;
|
||||
|
||||
// Intern the requested symbols: lookup takes interned strings.
|
||||
for (auto &S : Symbols)
|
||||
InternedSymbols.insert(ES.getSymbolStringPool().intern(S));
|
||||
|
||||
// Build an OnResolve callback to unwrap the interned strings and pass them
|
||||
// to the OnResolved callback.
|
||||
// FIXME: Switch to move capture of OnResolved once we have c++14.
|
||||
auto OnResolvedWithUnwrap =
|
||||
[OnResolved](Expected<SymbolMap> InternedResult) {
|
||||
if (!InternedResult) {
|
||||
OnResolved(InternedResult.takeError());
|
||||
return;
|
||||
}
|
||||
|
||||
LookupResult Result;
|
||||
for (auto &KV : *InternedResult)
|
||||
Result[*KV.first] = std::move(KV.second);
|
||||
OnResolved(Result);
|
||||
};
|
||||
|
||||
// We're not waiting for symbols to be ready. Just log any errors.
|
||||
auto OnReady = [&ES](Error Err) { ES.reportError(std::move(Err)); };
|
||||
|
||||
// Register dependencies for all symbols contained in this set.
|
||||
auto RegisterDependencies = [&](const SymbolDependenceMap &Deps) {
|
||||
MR.addDependenciesForAll(Deps);
|
||||
};
|
||||
|
||||
auto InternedResult =
|
||||
MR.getTargetJITDylib().withSearchOrderDo([&](const JITDylibList &JDs) {
|
||||
return ES.lookup(JDs, InternedSymbols, RegisterDependencies, false);
|
||||
});
|
||||
|
||||
if (!InternedResult)
|
||||
return InternedResult.takeError();
|
||||
|
||||
LookupResult Result;
|
||||
for (auto &KV : *InternedResult)
|
||||
Result[*KV.first] = std::move(KV.second);
|
||||
|
||||
return Result;
|
||||
MR.getTargetJITDylib().withSearchOrderDo([&](const JITDylibList &JDs) {
|
||||
ES.lookup(JDs, InternedSymbols, OnResolvedWithUnwrap, OnReady,
|
||||
RegisterDependencies);
|
||||
});
|
||||
}
|
||||
|
||||
Expected<LookupSet> getResponsibilitySet(const LookupSet &Symbols) {
|
||||
|
|
|
@ -62,34 +62,42 @@ llvm::ARMJITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) {
|
|||
/// Performs lookup by, for each symbol, first calling
|
||||
/// findSymbolInLogicalDylib and if that fails calling
|
||||
/// findSymbol.
|
||||
Expected<JITSymbolResolver::LookupResult>
|
||||
LegacyJITSymbolResolver::lookup(const LookupSet &Symbols) {
|
||||
void LegacyJITSymbolResolver::lookup(const LookupSet &Symbols,
|
||||
OnResolvedFunction OnResolved) {
|
||||
JITSymbolResolver::LookupResult Result;
|
||||
for (auto &Symbol : Symbols) {
|
||||
std::string SymName = Symbol.str();
|
||||
if (auto Sym = findSymbolInLogicalDylib(SymName)) {
|
||||
if (auto AddrOrErr = Sym.getAddress())
|
||||
Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());
|
||||
else
|
||||
return AddrOrErr.takeError();
|
||||
} else if (auto Err = Sym.takeError())
|
||||
return std::move(Err);
|
||||
else {
|
||||
else {
|
||||
OnResolved(AddrOrErr.takeError());
|
||||
return;
|
||||
}
|
||||
} else if (auto Err = Sym.takeError()) {
|
||||
OnResolved(std::move(Err));
|
||||
return;
|
||||
} else {
|
||||
// findSymbolInLogicalDylib failed. Lets try findSymbol.
|
||||
if (auto Sym = findSymbol(SymName)) {
|
||||
if (auto AddrOrErr = Sym.getAddress())
|
||||
Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());
|
||||
else
|
||||
return AddrOrErr.takeError();
|
||||
} else if (auto Err = Sym.takeError())
|
||||
return std::move(Err);
|
||||
else
|
||||
return make_error<StringError>("Symbol not found: " + Symbol,
|
||||
inconvertibleErrorCode());
|
||||
else {
|
||||
OnResolved(AddrOrErr.takeError());
|
||||
return;
|
||||
}
|
||||
} else if (auto Err = Sym.takeError()) {
|
||||
OnResolved(std::move(Err));
|
||||
return;
|
||||
} else {
|
||||
OnResolved(make_error<StringError>("Symbol not found: " + Symbol,
|
||||
inconvertibleErrorCode()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::move(Result);
|
||||
OnResolved(std::move(Result));
|
||||
}
|
||||
|
||||
/// Performs flags lookup by calling findSymbolInLogicalDylib and
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/MutexGuard.h"
|
||||
|
||||
#include <future>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::object;
|
||||
|
||||
|
@ -996,42 +998,8 @@ void RuntimeDyldImpl::resolveRelocationList(const RelocationList &Relocs,
|
|||
}
|
||||
}
|
||||
|
||||
Error RuntimeDyldImpl::resolveExternalSymbols() {
|
||||
StringMap<JITEvaluatedSymbol> ExternalSymbolMap;
|
||||
|
||||
// Resolution can trigger emission of more symbols, so iterate until
|
||||
// we've resolved *everything*.
|
||||
{
|
||||
JITSymbolResolver::LookupSet ResolvedSymbols;
|
||||
|
||||
while (true) {
|
||||
JITSymbolResolver::LookupSet NewSymbols;
|
||||
|
||||
for (auto &RelocKV : ExternalSymbolRelocations) {
|
||||
StringRef Name = RelocKV.first();
|
||||
if (!Name.empty() && !GlobalSymbolTable.count(Name) &&
|
||||
!ResolvedSymbols.count(Name))
|
||||
NewSymbols.insert(Name);
|
||||
}
|
||||
|
||||
if (NewSymbols.empty())
|
||||
break;
|
||||
|
||||
auto NewResolverResults = Resolver.lookup(NewSymbols);
|
||||
if (!NewResolverResults)
|
||||
return NewResolverResults.takeError();
|
||||
|
||||
assert(NewResolverResults->size() == NewSymbols.size() &&
|
||||
"Should have errored on unresolved symbols");
|
||||
|
||||
for (auto &RRKV : *NewResolverResults) {
|
||||
assert(!ResolvedSymbols.count(RRKV.first) && "Redundant resolution?");
|
||||
ExternalSymbolMap.insert(RRKV);
|
||||
ResolvedSymbols.insert(RRKV.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RuntimeDyldImpl::applyExternalSymbolRelocations(
|
||||
const StringMap<JITEvaluatedSymbol> ExternalSymbolMap) {
|
||||
while (!ExternalSymbolRelocations.empty()) {
|
||||
|
||||
StringMap<RelocationList>::iterator i = ExternalSymbolRelocations.begin();
|
||||
|
@ -1093,6 +1061,60 @@ Error RuntimeDyldImpl::resolveExternalSymbols() {
|
|||
|
||||
ExternalSymbolRelocations.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
Error RuntimeDyldImpl::resolveExternalSymbols() {
|
||||
StringMap<JITEvaluatedSymbol> ExternalSymbolMap;
|
||||
|
||||
// Resolution can trigger emission of more symbols, so iterate until
|
||||
// we've resolved *everything*.
|
||||
{
|
||||
JITSymbolResolver::LookupSet ResolvedSymbols;
|
||||
|
||||
while (true) {
|
||||
JITSymbolResolver::LookupSet NewSymbols;
|
||||
|
||||
for (auto &RelocKV : ExternalSymbolRelocations) {
|
||||
StringRef Name = RelocKV.first();
|
||||
if (!Name.empty() && !GlobalSymbolTable.count(Name) &&
|
||||
!ResolvedSymbols.count(Name))
|
||||
NewSymbols.insert(Name);
|
||||
}
|
||||
|
||||
if (NewSymbols.empty())
|
||||
break;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
using ExpectedLookupResult =
|
||||
MSVCPExpected<JITSymbolResolver::LooupResult>;
|
||||
#else
|
||||
using ExpectedLookupResult = Expected<JITSymbolResolver::LookupResult>;
|
||||
#endif
|
||||
|
||||
auto NewSymbolsP = std::make_shared<std::promise<ExpectedLookupResult>>();
|
||||
auto NewSymbolsF = NewSymbolsP->get_future();
|
||||
Resolver.lookup(NewSymbols,
|
||||
[=](Expected<JITSymbolResolver::LookupResult> Result) {
|
||||
NewSymbolsP->set_value(std::move(Result));
|
||||
});
|
||||
|
||||
auto NewResolverResults = NewSymbolsF.get();
|
||||
|
||||
if (!NewResolverResults)
|
||||
return NewResolverResults.takeError();
|
||||
|
||||
assert(NewResolverResults->size() == NewSymbols.size() &&
|
||||
"Should have errored on unresolved symbols");
|
||||
|
||||
for (auto &RRKV : *NewResolverResults) {
|
||||
assert(!ResolvedSymbols.count(RRKV.first) && "Redundant resolution?");
|
||||
ExternalSymbolMap.insert(RRKV);
|
||||
ResolvedSymbols.insert(RRKV.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
applyExternalSymbolRelocations(ExternalSymbolMap);
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include <cctype>
|
||||
#include <future>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
|
@ -729,15 +730,29 @@ bool RuntimeDyldCheckerImpl::checkAllRulesInBuffer(StringRef RulePrefix,
|
|||
return DidAllTestsPass && (NumRules != 0);
|
||||
}
|
||||
|
||||
Expected<JITSymbolResolver::LookupResult> RuntimeDyldCheckerImpl::lookup(
|
||||
const JITSymbolResolver::LookupSet &Symbols) const {
|
||||
auto ResultP = std::make_shared<
|
||||
std::promise<Expected<JITSymbolResolver::LookupResult>>>();
|
||||
auto ResultF = ResultP->get_future();
|
||||
|
||||
getRTDyld().Resolver.lookup(
|
||||
Symbols, [=](Expected<JITSymbolResolver::LookupResult> Result) {
|
||||
ResultP->set_value(std::move(Result));
|
||||
});
|
||||
return ResultF.get();
|
||||
}
|
||||
|
||||
bool RuntimeDyldCheckerImpl::isSymbolValid(StringRef Symbol) const {
|
||||
if (getRTDyld().getSymbol(Symbol))
|
||||
return true;
|
||||
JITSymbolResolver::LookupSet Symbols({Symbol});
|
||||
auto Result = getRTDyld().Resolver.lookup(Symbols);
|
||||
auto Result = lookup({Symbol});
|
||||
|
||||
if (!Result) {
|
||||
logAllUnhandledErrors(Result.takeError(), errs(), "RTDyldChecker: ");
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(Result->count(Symbol) && "Missing symbol result");
|
||||
return true;
|
||||
}
|
||||
|
@ -751,8 +766,7 @@ uint64_t RuntimeDyldCheckerImpl::getSymbolRemoteAddr(StringRef Symbol) const {
|
|||
if (auto InternalSymbol = getRTDyld().getSymbol(Symbol))
|
||||
return InternalSymbol.getAddress();
|
||||
|
||||
JITSymbolResolver::LookupSet Symbols({Symbol});
|
||||
auto Result = getRTDyld().Resolver.lookup(Symbols);
|
||||
auto Result = lookup({Symbol});
|
||||
if (!Result) {
|
||||
logAllUnhandledErrors(Result.takeError(), errs(), "RTDyldChecker: ");
|
||||
return 0;
|
||||
|
|
|
@ -41,6 +41,9 @@ private:
|
|||
|
||||
RuntimeDyldImpl &getRTDyld() const { return *RTDyld.Dyld; }
|
||||
|
||||
Expected<JITSymbolResolver::LookupResult>
|
||||
lookup(const JITSymbolResolver::LookupSet &Symbols) const;
|
||||
|
||||
bool isSymbolValid(StringRef Symbol) const;
|
||||
uint64_t getSymbolLocalAddr(StringRef Symbol) const;
|
||||
uint64_t getSymbolRemoteAddr(StringRef Symbol) const;
|
||||
|
|
|
@ -433,6 +433,9 @@ protected:
|
|||
const ObjectFile &Obj, ObjSectionToIDMap &ObjSectionToID,
|
||||
StubMap &Stubs) = 0;
|
||||
|
||||
void applyExternalSymbolRelocations(
|
||||
const StringMap<JITEvaluatedSymbol> ExternalSymbolMap);
|
||||
|
||||
/// Resolve relocations to external symbols.
|
||||
Error resolveExternalSymbols();
|
||||
|
||||
|
|
Loading…
Reference in New Issue