mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-26 14:16:12 +00:00
[ORC] Consolidate materialization errors, and generate them in VSO's
notifyFailed method rather than passing in an error generator. VSO::notifyFailed is responsible for notifying queries that they will not succeed due to error. In practice the queries don't care about the details of the failure, just the fact that a failure occurred for some symbols. Having VSO::notifyFailed take care of this simplifies the interface. llvm-svn: 332666
This commit is contained in:
parent
676e350789
commit
ddc80b6937
@ -65,39 +65,15 @@ using SymbolDependenceMap = std::map<VSO *, SymbolNameSet>;
|
||||
/// Render a SymbolDependendeMap.
|
||||
raw_ostream &operator<<(raw_ostream &OS, const SymbolDependenceMap &Deps);
|
||||
|
||||
/// A base class for materialization failures that allows the failing
|
||||
/// symbols to be obtained for logging.
|
||||
/// Used to notify a VSO that the given set of symbols failed to materialize.
|
||||
class FailedToMaterialize : public ErrorInfo<FailedToMaterialize> {
|
||||
public:
|
||||
static char ID;
|
||||
virtual const SymbolNameSet &getSymbols() const = 0;
|
||||
};
|
||||
|
||||
/// Used to notify a VSO that the given set of symbols failed to resolve.
|
||||
class FailedToResolve : public ErrorInfo<FailedToResolve, FailedToMaterialize> {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
FailedToResolve(SymbolNameSet Symbols);
|
||||
FailedToMaterialize(SymbolNameSet Symbols);
|
||||
std::error_code convertToErrorCode() const override;
|
||||
void log(raw_ostream &OS) const override;
|
||||
const SymbolNameSet &getSymbols() const override { return Symbols; }
|
||||
|
||||
private:
|
||||
SymbolNameSet Symbols;
|
||||
};
|
||||
|
||||
/// Used to notify a VSO that the given set of symbols failed to
|
||||
/// finalize.
|
||||
class FailedToFinalize
|
||||
: public ErrorInfo<FailedToFinalize, FailedToMaterialize> {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
FailedToFinalize(SymbolNameSet Symbols);
|
||||
std::error_code convertToErrorCode() const override;
|
||||
void log(raw_ostream &OS) const override;
|
||||
const SymbolNameSet &getSymbols() const override { return Symbols; }
|
||||
const SymbolNameSet &getSymbols() const { return Symbols; }
|
||||
|
||||
private:
|
||||
SymbolNameSet Symbols;
|
||||
@ -145,7 +121,7 @@ public:
|
||||
/// Notify all unfinalized symbols that an error has occurred.
|
||||
/// This will remove all symbols covered by this MaterializationResponsibilty
|
||||
/// from V, and send an error to any queries waiting on these symbols.
|
||||
void failMaterialization(std::function<Error()> GenerateError);
|
||||
void failMaterialization();
|
||||
|
||||
/// Transfers responsibility to the given MaterializationUnit for all
|
||||
/// symbols defined by that MaterializationUnit. This allows
|
||||
@ -552,8 +528,7 @@ public:
|
||||
/// Fail to materialize the given symbols.
|
||||
///
|
||||
/// Returns the list of queries that fail as a consequence.
|
||||
void notifyFailed(const SymbolFlagsMap &Failed,
|
||||
std::function<Error()> GenerateError);
|
||||
void notifyFailed(const SymbolNameSet &FailedSymbols);
|
||||
|
||||
/// Search the given VSO for the symbols in Symbols. If found, store
|
||||
/// the flags for each symbol in Flags. Returns any unresolved symbols.
|
||||
|
@ -20,8 +20,6 @@ namespace llvm {
|
||||
namespace orc {
|
||||
|
||||
char FailedToMaterialize::ID = 0;
|
||||
char FailedToResolve::ID = 0;
|
||||
char FailedToFinalize::ID = 0;
|
||||
|
||||
void MaterializationUnit::anchor() {}
|
||||
void SymbolResolver::anchor() {}
|
||||
@ -99,30 +97,17 @@ raw_ostream &operator<<(raw_ostream &OS, const SymbolDependenceMap &Deps) {
|
||||
return OS;
|
||||
}
|
||||
|
||||
FailedToResolve::FailedToResolve(SymbolNameSet Symbols)
|
||||
FailedToMaterialize::FailedToMaterialize(SymbolNameSet Symbols)
|
||||
: Symbols(std::move(Symbols)) {
|
||||
assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
|
||||
}
|
||||
|
||||
std::error_code FailedToResolve::convertToErrorCode() const {
|
||||
std::error_code FailedToMaterialize::convertToErrorCode() const {
|
||||
return orcError(OrcErrorCode::UnknownORCError);
|
||||
}
|
||||
|
||||
void FailedToResolve::log(raw_ostream &OS) const {
|
||||
OS << "Failed to resolve symbols: " << Symbols;
|
||||
}
|
||||
|
||||
FailedToFinalize::FailedToFinalize(SymbolNameSet Symbols)
|
||||
: Symbols(std::move(Symbols)) {
|
||||
assert(!this->Symbols.empty() && "Can not fail to finalize an empty set");
|
||||
}
|
||||
|
||||
std::error_code FailedToFinalize::convertToErrorCode() const {
|
||||
return orcError(OrcErrorCode::UnknownORCError);
|
||||
}
|
||||
|
||||
void FailedToFinalize::log(raw_ostream &OS) const {
|
||||
OS << "Failed to finalize symbols: " << Symbols;
|
||||
void FailedToMaterialize::log(raw_ostream &OS) const {
|
||||
OS << "Failed to materialize symbols: " << Symbols;
|
||||
}
|
||||
|
||||
void ExecutionSessionBase::failQuery(AsynchronousSymbolQuery &Q, Error Err) {
|
||||
@ -266,9 +251,13 @@ Error MaterializationResponsibility::defineMaterializing(
|
||||
return V.defineMaterializing(NewSymbolFlags);
|
||||
}
|
||||
|
||||
void MaterializationResponsibility::failMaterialization(
|
||||
std::function<Error()> GenerateError) {
|
||||
V.notifyFailed(SymbolFlags, std::move(GenerateError));
|
||||
void MaterializationResponsibility::failMaterialization() {
|
||||
|
||||
SymbolNameSet FailedSymbols;
|
||||
for (auto &KV : SymbolFlags)
|
||||
FailedSymbols.insert(KV.first);
|
||||
|
||||
V.notifyFailed(FailedSymbols);
|
||||
SymbolFlags.clear();
|
||||
}
|
||||
|
||||
@ -550,14 +539,14 @@ void VSO::finalize(const SymbolFlagsMap &Finalized) {
|
||||
}
|
||||
}
|
||||
|
||||
void VSO::notifyFailed(const SymbolFlagsMap &Failed,
|
||||
std::function<Error()> GenerateError) {
|
||||
void VSO::notifyFailed(const SymbolNameSet &FailedSymbols) {
|
||||
|
||||
// FIXME: This should fail any transitively dependant symbols too.
|
||||
|
||||
auto FailedQueriesToNotify = ES.runSessionLocked([&, this]() {
|
||||
AsynchronousSymbolQuerySet FailedQueries;
|
||||
|
||||
for (auto &KV : Failed) {
|
||||
const auto &Name = KV.first;
|
||||
|
||||
for (auto &Name : FailedSymbols) {
|
||||
auto I = Symbols.find(Name);
|
||||
assert(I != Symbols.end() && "Symbol not present in this VSO");
|
||||
Symbols.erase(I);
|
||||
@ -589,7 +578,7 @@ void VSO::notifyFailed(const SymbolFlagsMap &Failed,
|
||||
});
|
||||
|
||||
for (auto &Q : FailedQueriesToNotify)
|
||||
Q->handleFailed(GenerateError());
|
||||
Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbols));
|
||||
}
|
||||
|
||||
SymbolNameSet VSO::lookupFlags(SymbolFlagsMap &Flags,
|
||||
|
@ -518,91 +518,34 @@ TEST(CoreAPIsTest, FailResolution) {
|
||||
auto MU = llvm::make_unique<SimpleMaterializationUnit>(
|
||||
SymbolFlagsMap(
|
||||
{{Foo, JITSymbolFlags::Weak}, {Bar, JITSymbolFlags::Weak}}),
|
||||
[&](MaterializationResponsibility R) {
|
||||
R.failMaterialization(
|
||||
[&]() { return make_error<FailedToResolve>(Names); });
|
||||
});
|
||||
|
||||
auto &V = ES.createVSO("V");
|
||||
|
||||
cantFail(V.define(MU));
|
||||
|
||||
auto OnResolution = [&](Expected<AsynchronousSymbolQuery::ResolutionResult>
|
||||
Result) {
|
||||
handleAllErrors(Result.takeError(),
|
||||
[&](FailedToResolve &F) {
|
||||
EXPECT_EQ(F.getSymbols(), Names)
|
||||
<< "Expected to fail on symbols in Names";
|
||||
},
|
||||
[](ErrorInfoBase &EIB) {
|
||||
std::string ErrMsg;
|
||||
{
|
||||
raw_string_ostream ErrOut(ErrMsg);
|
||||
EIB.log(ErrOut);
|
||||
}
|
||||
ADD_FAILURE()
|
||||
<< "Expected a FailedToResolve error. Got:\n"
|
||||
<< ErrMsg;
|
||||
});
|
||||
};
|
||||
|
||||
auto OnReady = [](Error Err) {
|
||||
cantFail(std::move(Err));
|
||||
ADD_FAILURE() << "OnReady should never be called";
|
||||
};
|
||||
|
||||
auto Q =
|
||||
std::make_shared<AsynchronousSymbolQuery>(Names, OnResolution, OnReady);
|
||||
|
||||
V.lookup(std::move(Q), Names);
|
||||
}
|
||||
|
||||
TEST(CoreAPIsTest, FailFinalization) {
|
||||
ExecutionSession ES;
|
||||
auto Foo = ES.getSymbolStringPool().intern("foo");
|
||||
auto Bar = ES.getSymbolStringPool().intern("bar");
|
||||
|
||||
SymbolNameSet Names({Foo, Bar});
|
||||
|
||||
auto MU = llvm::make_unique<SimpleMaterializationUnit>(
|
||||
SymbolFlagsMap(
|
||||
{{Foo, JITSymbolFlags::Exported}, {Bar, JITSymbolFlags::Exported}}),
|
||||
[&](MaterializationResponsibility R) {
|
||||
constexpr JITTargetAddress FakeFooAddr = 0xdeadbeef;
|
||||
constexpr JITTargetAddress FakeBarAddr = 0xcafef00d;
|
||||
|
||||
auto FooSym = JITEvaluatedSymbol(FakeFooAddr, JITSymbolFlags::Exported);
|
||||
auto BarSym = JITEvaluatedSymbol(FakeBarAddr, JITSymbolFlags::Exported);
|
||||
R.resolve(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}));
|
||||
R.failMaterialization(
|
||||
[&]() { return make_error<FailedToFinalize>(Names); });
|
||||
});
|
||||
[&](MaterializationResponsibility R) { R.failMaterialization(); });
|
||||
|
||||
auto &V = ES.createVSO("V");
|
||||
|
||||
cantFail(V.define(MU));
|
||||
|
||||
auto OnResolution =
|
||||
[](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
|
||||
cantFail(std::move(Result));
|
||||
[&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
|
||||
handleAllErrors(Result.takeError(),
|
||||
[&](FailedToMaterialize &F) {
|
||||
EXPECT_EQ(F.getSymbols(), Names)
|
||||
<< "Expected to fail on symbols in Names";
|
||||
},
|
||||
[](ErrorInfoBase &EIB) {
|
||||
std::string ErrMsg;
|
||||
{
|
||||
raw_string_ostream ErrOut(ErrMsg);
|
||||
EIB.log(ErrOut);
|
||||
}
|
||||
ADD_FAILURE()
|
||||
<< "Expected a FailedToResolve error. Got:\n"
|
||||
<< ErrMsg;
|
||||
});
|
||||
};
|
||||
|
||||
auto OnReady = [&](Error Err) {
|
||||
handleAllErrors(std::move(Err),
|
||||
[&](FailedToFinalize &F) {
|
||||
EXPECT_EQ(F.getSymbols(), Names)
|
||||
<< "Expected to fail on symbols in Names";
|
||||
},
|
||||
[](ErrorInfoBase &EIB) {
|
||||
std::string ErrMsg;
|
||||
{
|
||||
raw_string_ostream ErrOut(ErrMsg);
|
||||
EIB.log(ErrOut);
|
||||
}
|
||||
ADD_FAILURE()
|
||||
<< "Expected a FailedToFinalize error. Got:\n"
|
||||
<< ErrMsg;
|
||||
});
|
||||
auto OnReady = [](Error Err) {
|
||||
cantFail(std::move(Err));
|
||||
ADD_FAILURE() << "OnReady should never be called";
|
||||
};
|
||||
|
||||
auto Q =
|
||||
|
Loading…
x
Reference in New Issue
Block a user