1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

[ORC] Make MaterializationResponsibility immovable, pass by unique_ptr.

Making MaterializationResponsibility instances immovable allows their
associated VModuleKeys to be updated by the ExecutionSession while the
responsibility is still in-flight. This will be used in the upcoming
removable code feature to enable safe merging of resource keys even if
there are active compiles using the keys being merged.
This commit is contained in:
Lang Hames 2020-09-10 13:10:27 -07:00
parent a8497a77ba
commit 9d3b846676
26 changed files with 314 additions and 274 deletions

View File

@ -113,14 +113,13 @@ private:
this->CODLayer.setImplMap(&Imps);
this->ES->setDispatchMaterialization(
[this](std::unique_ptr<MaterializationUnit> MU,
MaterializationResponsibility MR) {
// FIXME: Switch to move capture once we have C++14.
auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU));
auto SharedMR =
std::make_shared<MaterializationResponsibility>(std::move(MR));
CompileThreads.async([SharedMU, SharedMR]() {
SharedMU->materialize(std::move(*SharedMR));
});
std::unique_ptr<MaterializationResponsibility> MR) {
CompileThreads.async(
[UnownedMU = MU.release(), UnownedMR = MR.release()]() {
std::unique_ptr<MaterializationUnit> MU(UnownedMU);
std::unique_ptr<MaterializationResponsibility> MR(UnownedMR);
MU->materialize(std::move(MR));
});
});
ExitOnErr(S.addSpeculationRuntime(MainJD, Mangle));
LocalCXXRuntimeOverrides CXXRuntimeoverrides;

View File

@ -96,7 +96,8 @@ public:
/// Emits the given module. This should not be called by clients: it will be
/// called by the JIT when a definition added via the add method is requested.
void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
void emit(std::unique_ptr<MaterializationResponsibility> R,
ThreadSafeModule TSM) override;
private:
struct PerDylibResources {
@ -120,7 +121,8 @@ private:
void expandPartition(GlobalValueSet &Partition);
void emitPartition(MaterializationResponsibility R, ThreadSafeModule TSM,
void emitPartition(std::unique_ptr<MaterializationResponsibility> R,
ThreadSafeModule TSM,
IRMaterializationUnit::SymbolNameToDefinitionMap Defs);
mutable std::mutex CODLayerMutex;

View File

@ -410,7 +410,7 @@ private:
class MaterializationResponsibility {
friend class MaterializationUnit;
public:
MaterializationResponsibility(MaterializationResponsibility &&) = default;
MaterializationResponsibility(MaterializationResponsibility &&) = delete;
MaterializationResponsibility &
operator=(MaterializationResponsibility &&) = delete;
@ -514,8 +514,8 @@ public:
/// Delegates responsibility for the given symbols to the returned
/// materialization responsibility. Useful for breaking up work between
/// threads, or different kinds of materialization processes.
MaterializationResponsibility delegate(const SymbolNameSet &Symbols,
VModuleKey NewKey = VModuleKey());
std::unique_ptr<MaterializationResponsibility>
delegate(const SymbolNameSet &Symbols, VModuleKey NewKey = VModuleKey());
void addDependencies(const SymbolStringPtr &Name,
const SymbolDependenceMap &Dependencies);
@ -577,7 +577,8 @@ public:
/// Implementations of this method should materialize all symbols
/// in the materialzation unit, except for those that have been
/// previously discarded.
virtual void materialize(MaterializationResponsibility R) = 0;
virtual void
materialize(std::unique_ptr<MaterializationResponsibility> R) = 0;
/// Called by JITDylibs to notify MaterializationUnits that the given symbol
/// has been overridden.
@ -594,10 +595,11 @@ protected:
private:
virtual void anchor();
MaterializationResponsibility
std::unique_ptr<MaterializationResponsibility>
createMaterializationResponsibility(std::shared_ptr<JITDylib> JD) {
return MaterializationResponsibility(std::move(JD), std::move(SymbolFlags),
std::move(InitSymbol), K);
return std::unique_ptr<MaterializationResponsibility>(
new MaterializationResponsibility(std::move(JD), std::move(SymbolFlags),
std::move(InitSymbol), K));
}
/// Implementations of this method should discard the given symbol
@ -621,7 +623,7 @@ public:
StringRef getName() const override;
private:
void materialize(MaterializationResponsibility R) override;
void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
static SymbolFlagsMap extractFlags(const SymbolMap &Symbols);
@ -663,7 +665,7 @@ public:
StringRef getName() const override;
private:
void materialize(MaterializationResponsibility R) override;
void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases);
@ -1116,7 +1118,7 @@ public:
/// For dispatching MaterializationUnit::materialize calls.
using DispatchMaterializationFunction =
std::function<void(std::unique_ptr<MaterializationUnit> MU,
MaterializationResponsibility MR)>;
std::unique_ptr<MaterializationResponsibility> MR)>;
/// Construct an ExecutionSession.
///
@ -1268,10 +1270,11 @@ public:
SymbolState RequiredState = SymbolState::Ready);
/// Materialize the given unit.
void dispatchMaterialization(std::unique_ptr<MaterializationUnit> MU,
MaterializationResponsibility MR) {
void
dispatchMaterialization(std::unique_ptr<MaterializationUnit> MU,
std::unique_ptr<MaterializationResponsibility> MR) {
assert(MU && "MU must be non-null");
DEBUG_WITH_TYPE("orc", dumpDispatchInfo(MR.getTargetJITDylib(), *MU));
DEBUG_WITH_TYPE("orc", dumpDispatchInfo(MR->getTargetJITDylib(), *MU));
DispatchMaterialization(std::move(MU), std::move(MR));
}
@ -1283,9 +1286,9 @@ private:
logAllUnhandledErrors(std::move(Err), errs(), "JIT session error: ");
}
static void
materializeOnCurrentThread(std::unique_ptr<MaterializationUnit> MU,
MaterializationResponsibility MR) {
static void materializeOnCurrentThread(
std::unique_ptr<MaterializationUnit> MU,
std::unique_ptr<MaterializationResponsibility> MR) {
MU->materialize(std::move(MR));
}
@ -1309,7 +1312,7 @@ private:
// with callbacks from asynchronous queries.
mutable std::recursive_mutex OutstandingMUsMutex;
std::vector<std::pair<std::unique_ptr<MaterializationUnit>,
MaterializationResponsibility>>
std::unique_ptr<MaterializationResponsibility>>>
OutstandingMUs;
};

View File

@ -55,7 +55,8 @@ public:
void setNotifyCompiled(NotifyCompiledFunction NotifyCompiled);
void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
void emit(std::unique_ptr<MaterializationResponsibility> R,
ThreadSafeModule TSM) override;
private:
mutable std::mutex IRLayerMutex;

View File

@ -37,7 +37,8 @@ public:
this->Transform = std::move(Transform);
}
void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
void emit(std::unique_ptr<MaterializationResponsibility> R,
ThreadSafeModule TSM) override;
static ThreadSafeModule identityTransform(ThreadSafeModule TSM,
MaterializationResponsibility &R) {

View File

@ -100,7 +100,8 @@ public:
VModuleKey K = VModuleKey());
/// Emit should materialize the given IR.
virtual void emit(MaterializationResponsibility R, ThreadSafeModule TSM) = 0;
virtual void emit(std::unique_ptr<MaterializationResponsibility> R,
ThreadSafeModule TSM) = 0;
private:
bool CloneToNewContextOnEmit = false;
@ -117,8 +118,7 @@ public:
ThreadSafeModule TSM, VModuleKey K);
private:
void materialize(MaterializationResponsibility R) override;
void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
IRLayer &L;
VModuleKey K;
@ -139,7 +139,7 @@ public:
VModuleKey K = VModuleKey());
/// Emit should materialize the given IR.
virtual void emit(MaterializationResponsibility R,
virtual void emit(std::unique_ptr<MaterializationResponsibility> R,
std::unique_ptr<MemoryBuffer> O) = 0;
private:
@ -162,8 +162,7 @@ public:
StringRef getName() const override;
private:
void materialize(MaterializationResponsibility R) override;
void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
ObjectLayer &L;

View File

@ -149,7 +149,7 @@ public:
StringRef getName() const override;
private:
void materialize(MaterializationResponsibility R) override;
void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases);

View File

@ -119,7 +119,7 @@ public:
}
/// Emit the object.
void emit(MaterializationResponsibility R,
void emit(std::unique_ptr<MaterializationResponsibility> R,
std::unique_ptr<MemoryBuffer> O) override;
/// Instructs this ObjectLinkingLayer instance to override the symbol flags

View File

@ -31,7 +31,7 @@ public:
ObjectTransformLayer(ExecutionSession &ES, ObjectLayer &BaseLayer,
TransformFunction Transform = TransformFunction());
void emit(MaterializationResponsibility R,
void emit(std::unique_ptr<MaterializationResponsibility> R,
std::unique_ptr<MemoryBuffer> O) override;
void setTransform(TransformFunction Transform) {

View File

@ -58,7 +58,7 @@ public:
~RTDyldObjectLinkingLayer();
/// Emit the object.
void emit(MaterializationResponsibility R,
void emit(std::unique_ptr<MaterializationResponsibility> R,
std::unique_ptr<MemoryBuffer> O) override;
/// Set the NotifyLoaded callback.

View File

@ -181,7 +181,8 @@ public:
: IRLayer(ES, BaseLayer.getManglingOptions()), NextLayer(BaseLayer),
S(Spec), Mangle(Mangle), QueryAnalysis(Interpreter) {}
void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
void emit(std::unique_ptr<MaterializationResponsibility> R,
ThreadSafeModule TSM) override;
private:
TargetAndLikelies

View File

@ -88,7 +88,7 @@ public:
Parent(Parent) {}
private:
void materialize(MaterializationResponsibility R) override {
void materialize(std::unique_ptr<MaterializationResponsibility> R) override {
Parent.emitPartition(std::move(R), std::move(TSM),
std::move(SymbolToDefinition));
}
@ -128,15 +128,15 @@ void CompileOnDemandLayer::setPartitionFunction(PartitionFunction Partition) {
void CompileOnDemandLayer::setImplMap(ImplSymbolMap *Imp) {
this->AliaseeImpls = Imp;
}
void CompileOnDemandLayer::emit(MaterializationResponsibility R,
ThreadSafeModule TSM) {
void CompileOnDemandLayer::emit(
std::unique_ptr<MaterializationResponsibility> R, ThreadSafeModule TSM) {
assert(TSM && "Null module");
auto &ES = getExecutionSession();
// Sort the callables and non-callables, build re-exports and lodge the
// actual module with the implementation dylib.
auto &PDR = getPerDylibResources(R.getTargetJITDylib());
auto &PDR = getPerDylibResources(R->getTargetJITDylib());
SymbolAliasMap NonCallables;
SymbolAliasMap Callables;
@ -145,7 +145,7 @@ void CompileOnDemandLayer::emit(MaterializationResponsibility R,
cleanUpModule(M);
});
for (auto &KV : R.getSymbols()) {
for (auto &KV : R->getSymbols()) {
auto &Name = KV.first;
auto &Flags = KV.second;
if (Flags.isCallable())
@ -158,19 +158,19 @@ void CompileOnDemandLayer::emit(MaterializationResponsibility R,
// implementation dylib.
if (auto Err = PDR.getImplDylib().define(
std::make_unique<PartitioningIRMaterializationUnit>(
ES, *getManglingOptions(), std::move(TSM), R.getVModuleKey(),
ES, *getManglingOptions(), std::move(TSM), R->getVModuleKey(),
*this))) {
ES.reportError(std::move(Err));
R.failMaterialization();
R->failMaterialization();
return;
}
if (!NonCallables.empty())
R.replace(reexports(PDR.getImplDylib(), std::move(NonCallables),
JITDylibLookupFlags::MatchAllSymbols));
R->replace(reexports(PDR.getImplDylib(), std::move(NonCallables),
JITDylibLookupFlags::MatchAllSymbols));
if (!Callables.empty())
R.replace(lazyReexports(LCTMgr, PDR.getISManager(), PDR.getImplDylib(),
std::move(Callables), AliaseeImpls));
R->replace(lazyReexports(LCTMgr, PDR.getISManager(), PDR.getImplDylib(),
std::move(Callables), AliaseeImpls));
}
CompileOnDemandLayer::PerDylibResources &
@ -247,7 +247,7 @@ void CompileOnDemandLayer::expandPartition(GlobalValueSet &Partition) {
}
void CompileOnDemandLayer::emitPartition(
MaterializationResponsibility R, ThreadSafeModule TSM,
std::unique_ptr<MaterializationResponsibility> R, ThreadSafeModule TSM,
IRMaterializationUnit::SymbolNameToDefinitionMap Defs) {
// FIXME: Need a 'notify lazy-extracting/emitting' callback to tie the
@ -257,8 +257,8 @@ void CompileOnDemandLayer::emitPartition(
auto &ES = getExecutionSession();
GlobalValueSet RequestedGVs;
for (auto &Name : R.getRequestedSymbols()) {
if (Name == R.getInitializerSymbol())
for (auto &Name : R->getRequestedSymbols()) {
if (Name == R->getInitializerSymbol())
TSM.withModuleDo([&](Module &M) {
for (auto &GV : getStaticInitGVs(M))
RequestedGVs.insert(&GV);
@ -285,9 +285,9 @@ void CompileOnDemandLayer::emitPartition(
// If the partition is empty, return the whole module to the symbol table.
if (GVsToExtract->empty()) {
R.replace(std::make_unique<PartitioningIRMaterializationUnit>(
std::move(TSM), R.getVModuleKey(), R.getSymbols(),
R.getInitializerSymbol(), std::move(Defs), *this));
R->replace(std::make_unique<PartitioningIRMaterializationUnit>(
std::move(TSM), R->getVModuleKey(), R->getSymbols(),
R->getInitializerSymbol(), std::move(Defs), *this));
return;
}
@ -308,7 +308,7 @@ void CompileOnDemandLayer::emitPartition(
IRSymbolMapper::add(ES, *getManglingOptions(),
PromotedGlobals, SymbolFlags);
if (auto Err = R.defineMaterializing(SymbolFlags))
if (auto Err = R->defineMaterializing(SymbolFlags))
return std::move(Err);
}
@ -348,12 +348,12 @@ void CompileOnDemandLayer::emitPartition(
if (!ExtractedTSM) {
ES.reportError(ExtractedTSM.takeError());
R.failMaterialization();
R->failMaterialization();
return;
}
R.replace(std::make_unique<PartitioningIRMaterializationUnit>(
ES, *getManglingOptions(), std::move(TSM), R.getVModuleKey(), *this));
R->replace(std::make_unique<PartitioningIRMaterializationUnit>(
ES, *getManglingOptions(), std::move(TSM), R->getVModuleKey(), *this));
BaseLayer.emit(std::move(R), std::move(*ExtractedTSM));
}

View File

@ -279,7 +279,7 @@ void MaterializationResponsibility::replace(
JD->replace(std::move(MU));
}
MaterializationResponsibility
std::unique_ptr<MaterializationResponsibility>
MaterializationResponsibility::delegate(const SymbolNameSet &Symbols,
VModuleKey NewKey) {
@ -302,9 +302,10 @@ MaterializationResponsibility::delegate(const SymbolNameSet &Symbols,
SymbolFlags.erase(I);
}
return MaterializationResponsibility(JD, std::move(DelegatedFlags),
std::move(DelegatedInitSymbol),
std::move(NewKey));
return std::unique_ptr<MaterializationResponsibility>(
new MaterializationResponsibility(JD, std::move(DelegatedFlags),
std::move(DelegatedInitSymbol),
std::move(NewKey)));
}
void MaterializationResponsibility::addDependencies(
@ -338,10 +339,10 @@ StringRef AbsoluteSymbolsMaterializationUnit::getName() const {
}
void AbsoluteSymbolsMaterializationUnit::materialize(
MaterializationResponsibility R) {
std::unique_ptr<MaterializationResponsibility> R) {
// No dependencies, so these calls can't fail.
cantFail(R.notifyResolved(Symbols));
cantFail(R.notifyEmitted());
cantFail(R->notifyResolved(Symbols));
cantFail(R->notifyEmitted());
}
void AbsoluteSymbolsMaterializationUnit::discard(const JITDylib &JD,
@ -370,16 +371,16 @@ StringRef ReExportsMaterializationUnit::getName() const {
}
void ReExportsMaterializationUnit::materialize(
MaterializationResponsibility R) {
std::unique_ptr<MaterializationResponsibility> R) {
auto &ES = R.getTargetJITDylib().getExecutionSession();
JITDylib &TgtJD = R.getTargetJITDylib();
auto &ES = R->getTargetJITDylib().getExecutionSession();
JITDylib &TgtJD = R->getTargetJITDylib();
JITDylib &SrcJD = SourceJD ? *SourceJD : TgtJD;
// Find the set of requested aliases and aliasees. Return any unrequested
// aliases back to the JITDylib so as to not prematurely materialize any
// aliasees.
auto RequestedSymbols = R.getRequestedSymbols();
auto RequestedSymbols = R->getRequestedSymbols();
SymbolAliasMap RequestedAliases;
for (auto &Name : RequestedSymbols) {
@ -399,18 +400,19 @@ void ReExportsMaterializationUnit::materialize(
if (!Aliases.empty()) {
if (SourceJD)
R.replace(reexports(*SourceJD, std::move(Aliases), SourceJDLookupFlags));
R->replace(reexports(*SourceJD, std::move(Aliases), SourceJDLookupFlags));
else
R.replace(symbolAliases(std::move(Aliases)));
R->replace(symbolAliases(std::move(Aliases)));
}
// The OnResolveInfo struct will hold the aliases and responsibilty for each
// query in the list.
struct OnResolveInfo {
OnResolveInfo(MaterializationResponsibility R, SymbolAliasMap Aliases)
OnResolveInfo(std::unique_ptr<MaterializationResponsibility> R,
SymbolAliasMap Aliases)
: R(std::move(R)), Aliases(std::move(Aliases)) {}
MaterializationResponsibility R;
std::unique_ptr<MaterializationResponsibility> R;
SymbolAliasMap Aliases;
};
@ -451,7 +453,7 @@ void ReExportsMaterializationUnit::materialize(
assert(!QuerySymbols.empty() && "Alias cycle detected!");
auto QueryInfo = std::make_shared<OnResolveInfo>(
R.delegate(ResponsibilitySymbols), std::move(QueryAliases));
R->delegate(ResponsibilitySymbols), std::move(QueryAliases));
QueryInfos.push_back(
make_pair(std::move(QuerySymbols), std::move(QueryInfo)));
}
@ -480,12 +482,12 @@ void ReExportsMaterializationUnit::materialize(
for (auto &KV : QueryInfo->Aliases)
if (SrcJDDeps.count(KV.second.Aliasee)) {
PerAliasDeps = {KV.second.Aliasee};
QueryInfo->R.addDependencies(KV.first, PerAliasDepsMap);
QueryInfo->R->addDependencies(KV.first, PerAliasDepsMap);
}
};
auto OnComplete = [QueryInfo](Expected<SymbolMap> Result) {
auto &ES = QueryInfo->R.getTargetJITDylib().getExecutionSession();
auto &ES = QueryInfo->R->getTargetJITDylib().getExecutionSession();
if (Result) {
SymbolMap ResolutionMap;
for (auto &KV : QueryInfo->Aliases) {
@ -499,19 +501,19 @@ void ReExportsMaterializationUnit::materialize(
ResolutionMap[KV.first] = JITEvaluatedSymbol(
(*Result)[KV.second.Aliasee].getAddress(), KV.second.AliasFlags);
}
if (auto Err = QueryInfo->R.notifyResolved(ResolutionMap)) {
if (auto Err = QueryInfo->R->notifyResolved(ResolutionMap)) {
ES.reportError(std::move(Err));
QueryInfo->R.failMaterialization();
QueryInfo->R->failMaterialization();
return;
}
if (auto Err = QueryInfo->R.notifyEmitted()) {
if (auto Err = QueryInfo->R->notifyEmitted()) {
ES.reportError(std::move(Err));
QueryInfo->R.failMaterialization();
QueryInfo->R->failMaterialization();
return;
}
} else {
ES.reportError(Result.takeError());
QueryInfo->R.failMaterialization();
QueryInfo->R->failMaterialization();
}
};
@ -2131,7 +2133,7 @@ void ExecutionSession::dump(raw_ostream &OS) {
void ExecutionSession::runOutstandingMUs() {
while (1) {
Optional<std::pair<std::unique_ptr<MaterializationUnit>,
MaterializationResponsibility>>
std::unique_ptr<MaterializationResponsibility>>>
JMU;
{

View File

@ -25,7 +25,7 @@ void IRCompileLayer::setNotifyCompiled(NotifyCompiledFunction NotifyCompiled) {
this->NotifyCompiled = std::move(NotifyCompiled);
}
void IRCompileLayer::emit(MaterializationResponsibility R,
void IRCompileLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
ThreadSafeModule TSM) {
assert(TSM && "Module must not be null");
@ -33,13 +33,13 @@ void IRCompileLayer::emit(MaterializationResponsibility R,
{
std::lock_guard<std::mutex> Lock(IRLayerMutex);
if (NotifyCompiled)
NotifyCompiled(R.getVModuleKey(), std::move(TSM));
NotifyCompiled(R->getVModuleKey(), std::move(TSM));
else
TSM = ThreadSafeModule();
}
BaseLayer.emit(std::move(R), std::move(*Obj));
} else {
R.failMaterialization();
R->failMaterialization();
getExecutionSession().reportError(Obj.takeError());
}
}

View File

@ -17,14 +17,14 @@ IRTransformLayer::IRTransformLayer(ExecutionSession &ES, IRLayer &BaseLayer,
: IRLayer(ES, BaseLayer.getManglingOptions()), BaseLayer(BaseLayer),
Transform(std::move(Transform)) {}
void IRTransformLayer::emit(MaterializationResponsibility R,
void IRTransformLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
ThreadSafeModule TSM) {
assert(TSM && "Module must not be null");
if (auto TransformedTSM = Transform(std::move(TSM), R))
if (auto TransformedTSM = Transform(std::move(TSM), *R))
BaseLayer.emit(std::move(R), std::move(*TransformedTSM));
else {
R.failMaterialization();
R->failMaterialization();
getExecutionSession().reportError(TransformedTSM.takeError());
}
}

View File

@ -33,12 +33,12 @@ public:
StringRef getName() const override { return "<Compile Callbacks>"; }
private:
void materialize(MaterializationResponsibility R) override {
void materialize(std::unique_ptr<MaterializationResponsibility> R) override {
SymbolMap Result;
Result[Name] = JITEvaluatedSymbol(Compile(), JITSymbolFlags::Exported);
// No dependencies, so these calls cannot fail.
cantFail(R.notifyResolved(Result));
cantFail(R.notifyEmitted());
cantFail(R->notifyResolved(Result));
cantFail(R->notifyEmitted());
}
void discard(const JITDylib &JD, const SymbolStringPtr &Name) override {

View File

@ -1085,15 +1085,17 @@ LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)
std::make_unique<ThreadPool>(hardware_concurrency(S.NumCompileThreads));
ES->setDispatchMaterialization(
[this](std::unique_ptr<MaterializationUnit> MU,
MaterializationResponsibility MR) {
// FIXME: Switch to move capture once ThreadPool uses unique_function.
auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU));
auto SharedMR =
std::make_shared<MaterializationResponsibility>(std::move(MR));
auto Work = [SharedMU, SharedMR]() mutable {
SharedMU->materialize(std::move(*SharedMR));
};
CompileThreads->async(std::move(Work));
std::unique_ptr<MaterializationResponsibility> MR) {
// FIXME: We should be able to use move-capture here, but ThreadPool's
// AsyncTaskTys are std::functions rather than unique_functions
// (because MSVC's std::packaged_tasks don't support move-only types).
// Fix this when all the above gets sorted out.
CompileThreads->async(
[UnownedMU = MU.release(), UnownedMR = MR.release()]() mutable {
std::unique_ptr<MaterializationUnit> MU(UnownedMU);
std::unique_ptr<MaterializationResponsibility> MR(UnownedMR);
MU->materialize(std::move(MR));
});
});
}

View File

@ -133,7 +133,7 @@ BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit(
L(L), K(std::move(K)) {}
void BasicIRLayerMaterializationUnit::materialize(
MaterializationResponsibility R) {
std::unique_ptr<MaterializationResponsibility> R) {
// Throw away the SymbolToDefinition map: it's not usable after we hand
// off the module.
@ -144,8 +144,8 @@ void BasicIRLayerMaterializationUnit::materialize(
TSM = cloneToNewContext(TSM);
#ifndef NDEBUG
auto &ES = R.getTargetJITDylib().getExecutionSession();
auto &N = R.getTargetJITDylib().getName();
auto &ES = R->getTargetJITDylib().getExecutionSession();
auto &N = R->getTargetJITDylib().getName();
#endif // NDEBUG
LLVM_DEBUG(ES.runSessionLocked(
@ -200,7 +200,7 @@ StringRef BasicObjectLayerMaterializationUnit::getName() const {
}
void BasicObjectLayerMaterializationUnit::materialize(
MaterializationResponsibility R) {
std::unique_ptr<MaterializationResponsibility> R) {
L.emit(std::move(R), std::move(O));
}

View File

@ -154,8 +154,8 @@ StringRef LazyReexportsMaterializationUnit::getName() const {
}
void LazyReexportsMaterializationUnit::materialize(
MaterializationResponsibility R) {
auto RequestedSymbols = R.getRequestedSymbols();
std::unique_ptr<MaterializationResponsibility> R) {
auto RequestedSymbols = R->getRequestedSymbols();
SymbolAliasMap RequestedAliases;
for (auto &RequestedSymbol : RequestedSymbols) {
@ -166,8 +166,8 @@ void LazyReexportsMaterializationUnit::materialize(
}
if (!CallableAliases.empty())
R.replace(lazyReexports(LCTManager, ISManager, SourceJD,
std::move(CallableAliases), AliaseeTable));
R->replace(lazyReexports(LCTManager, ISManager, SourceJD,
std::move(CallableAliases), AliaseeTable));
IndirectStubsManager::StubInitsMap StubInits;
for (auto &Alias : RequestedAliases) {
@ -182,7 +182,7 @@ void LazyReexportsMaterializationUnit::materialize(
if (!CallThroughTrampoline) {
SourceJD.getExecutionSession().reportError(
CallThroughTrampoline.takeError());
R.failMaterialization();
R->failMaterialization();
return;
}
@ -195,7 +195,7 @@ void LazyReexportsMaterializationUnit::materialize(
if (auto Err = ISManager.createStubs(StubInits)) {
SourceJD.getExecutionSession().reportError(std::move(Err));
R.failMaterialization();
R->failMaterialization();
return;
}
@ -204,8 +204,8 @@ void LazyReexportsMaterializationUnit::materialize(
Stubs[Alias.first] = ISManager.findStub(*Alias.first, false);
// No registered dependencies, so these calls cannot fail.
cantFail(R.notifyResolved(Stubs));
cantFail(R.notifyEmitted());
cantFail(R->notifyResolved(Stubs));
cantFail(R->notifyEmitted());
}
void LazyReexportsMaterializationUnit::discard(const JITDylib &JD,

View File

@ -24,9 +24,10 @@ namespace orc {
class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
public:
ObjectLinkingLayerJITLinkContext(ObjectLinkingLayer &Layer,
MaterializationResponsibility MR,
std::unique_ptr<MemoryBuffer> ObjBuffer)
ObjectLinkingLayerJITLinkContext(
ObjectLinkingLayer &Layer,
std::unique_ptr<MaterializationResponsibility> MR,
std::unique_ptr<MemoryBuffer> ObjBuffer)
: Layer(Layer), MR(std::move(MR)), ObjBuffer(std::move(ObjBuffer)) {}
~ObjectLinkingLayerJITLinkContext() {
@ -44,14 +45,14 @@ public:
void notifyFailed(Error Err) override {
Layer.getExecutionSession().reportError(std::move(Err));
MR.failMaterialization();
MR->failMaterialization();
}
void lookup(const LookupMap &Symbols,
std::unique_ptr<JITLinkAsyncLookupContinuation> LC) override {
JITDylibSearchOrder LinkOrder;
MR.getTargetJITDylib().withLinkOrderDo(
MR->getTargetJITDylib().withLinkOrderDo(
[&](const JITDylibSearchOrder &LO) { LinkOrder = LO; });
auto &ES = Layer.getExecutionSession();
@ -85,8 +86,8 @@ public:
for (auto &KV : InternalNamedSymbolDeps) {
SymbolDependenceMap InternalDeps;
InternalDeps[&MR.getTargetJITDylib()] = std::move(KV.second);
MR.addDependencies(KV.first, InternalDeps);
InternalDeps[&MR->getTargetJITDylib()] = std::move(KV.second);
MR->addDependencies(KV.first, InternalDeps);
}
ES.lookup(LookupKind::Static, LinkOrder, std::move(LookupSet),
@ -115,7 +116,7 @@ public:
InternedResult[InternedName] =
JITEvaluatedSymbol(Sym->getAddress(), Flags);
if (AutoClaim && !MR.getSymbols().count(InternedName)) {
if (AutoClaim && !MR->getSymbols().count(InternedName)) {
assert(!ExtraSymbolsToClaim.count(InternedName) &&
"Duplicate symbol to claim?");
ExtraSymbolsToClaim[InternedName] = Flags;
@ -133,7 +134,7 @@ public:
Flags |= JITSymbolFlags::Weak;
InternedResult[InternedName] =
JITEvaluatedSymbol(Sym->getAddress(), Flags);
if (AutoClaim && !MR.getSymbols().count(InternedName)) {
if (AutoClaim && !MR->getSymbols().count(InternedName)) {
assert(!ExtraSymbolsToClaim.count(InternedName) &&
"Duplicate symbol to claim?");
ExtraSymbolsToClaim[InternedName] = Flags;
@ -141,19 +142,19 @@ public:
}
if (!ExtraSymbolsToClaim.empty())
if (auto Err = MR.defineMaterializing(ExtraSymbolsToClaim))
if (auto Err = MR->defineMaterializing(ExtraSymbolsToClaim))
return Err;
{
// Check that InternedResult matches up with MR.getSymbols().
// Check that InternedResult matches up with MR->getSymbols().
// This guards against faulty transformations / compilers / object caches.
// First check that there aren't any missing symbols.
size_t NumMaterializationSideEffectsOnlySymbols = 0;
SymbolNameVector ExtraSymbols;
SymbolNameVector MissingSymbols;
for (auto &KV : MR.getSymbols()) {
for (auto &KV : MR->getSymbols()) {
// If this is a materialization-side-effects only symbol then bump
// the counter and make sure it's *not* defined, otherwise make
@ -175,9 +176,9 @@ public:
// If there are more definitions than expected, add them to the
// ExtraSymbols vector.
if (InternedResult.size() >
MR.getSymbols().size() - NumMaterializationSideEffectsOnlySymbols) {
MR->getSymbols().size() - NumMaterializationSideEffectsOnlySymbols) {
for (auto &KV : InternedResult)
if (!MR.getSymbols().count(KV.first))
if (!MR->getSymbols().count(KV.first))
ExtraSymbols.push_back(KV.first);
}
@ -187,23 +188,23 @@ public:
std::move(ExtraSymbols));
}
if (auto Err = MR.notifyResolved(InternedResult))
if (auto Err = MR->notifyResolved(InternedResult))
return Err;
Layer.notifyLoaded(MR);
Layer.notifyLoaded(*MR);
return Error::success();
}
void notifyFinalized(
std::unique_ptr<JITLinkMemoryManager::Allocation> A) override {
if (auto Err = Layer.notifyEmitted(MR, std::move(A))) {
if (auto Err = Layer.notifyEmitted(*MR, std::move(A))) {
Layer.getExecutionSession().reportError(std::move(Err));
MR.failMaterialization();
MR->failMaterialization();
return;
}
if (auto Err = MR.notifyEmitted()) {
if (auto Err = MR->notifyEmitted()) {
Layer.getExecutionSession().reportError(std::move(Err));
MR.failMaterialization();
MR->failMaterialization();
}
}
@ -217,7 +218,7 @@ public:
Config.PrePrunePasses.push_back(
[this](LinkGraph &G) { return externalizeWeakAndCommonSymbols(G); });
Layer.modifyPassConfig(MR, TT, Config);
Layer.modifyPassConfig(*MR, TT, Config);
Config.PostPrunePasses.push_back(
[this](LinkGraph &G) { return computeNamedSymbolDependencies(G); });
@ -237,13 +238,13 @@ private:
auto &ES = Layer.getExecutionSession();
for (auto *Sym : G.defined_symbols())
if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) {
if (!MR.getSymbols().count(ES.intern(Sym->getName())))
if (!MR->getSymbols().count(ES.intern(Sym->getName())))
G.makeExternal(*Sym);
}
for (auto *Sym : G.absolute_symbols())
if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) {
if (!MR.getSymbols().count(ES.intern(Sym->getName())))
if (!MR->getSymbols().count(ES.intern(Sym->getName())))
G.makeExternal(*Sym);
}
@ -253,13 +254,13 @@ private:
Error markResponsibilitySymbolsLive(LinkGraph &G) const {
auto &ES = Layer.getExecutionSession();
for (auto *Sym : G.defined_symbols())
if (Sym->hasName() && MR.getSymbols().count(ES.intern(Sym->getName())))
if (Sym->hasName() && MR->getSymbols().count(ES.intern(Sym->getName())))
Sym->setLive(true);
return Error::success();
}
Error computeNamedSymbolDependencies(LinkGraph &G) {
auto &ES = MR.getTargetJITDylib().getExecutionSession();
auto &ES = MR->getTargetJITDylib().getExecutionSession();
auto LocalDeps = computeLocalDeps(G);
// Compute dependencies for symbols defined in the JITLink graph.
@ -306,7 +307,7 @@ private:
}
for (auto &P : Layer.Plugins) {
auto SyntheticLocalDeps = P->getSyntheticSymbolLocalDependencies(MR);
auto SyntheticLocalDeps = P->getSyntheticSymbolLocalDependencies(*MR);
if (SyntheticLocalDeps.empty())
continue;
@ -426,12 +427,12 @@ private:
SymbolDeps.erase(&SourceJD);
}
MR.addDependencies(Name, SymbolDeps);
MR->addDependencies(Name, SymbolDeps);
}
}
ObjectLinkingLayer &Layer;
MaterializationResponsibility MR;
std::unique_ptr<MaterializationResponsibility> MR;
std::unique_ptr<MemoryBuffer> ObjBuffer;
DenseMap<SymbolStringPtr, SymbolNameSet> ExternalNamedSymbolDeps;
DenseMap<SymbolStringPtr, SymbolNameSet> InternalNamedSymbolDeps;
@ -452,7 +453,7 @@ ObjectLinkingLayer::~ObjectLinkingLayer() {
getExecutionSession().reportError(std::move(Err));
}
void ObjectLinkingLayer::emit(MaterializationResponsibility R,
void ObjectLinkingLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
std::unique_ptr<MemoryBuffer> O) {
assert(O && "Object must not be null");
jitLink(std::make_unique<ObjectLinkingLayerJITLinkContext>(

View File

@ -17,8 +17,9 @@ ObjectTransformLayer::ObjectTransformLayer(ExecutionSession &ES,
TransformFunction Transform)
: ObjectLayer(ES), BaseLayer(BaseLayer), Transform(std::move(Transform)) {}
void ObjectTransformLayer::emit(MaterializationResponsibility R,
std::unique_ptr<MemoryBuffer> O) {
void ObjectTransformLayer::emit(
std::unique_ptr<MaterializationResponsibility> R,
std::unique_ptr<MemoryBuffer> O) {
assert(O && "Module must not be null");
// If there is a transform set then apply it.
@ -26,7 +27,7 @@ void ObjectTransformLayer::emit(MaterializationResponsibility R,
if (auto TransformedObj = Transform(std::move(O)))
O = std::move(*TransformedObj);
else {
R.failMaterialization();
R->failMaterialization();
getExecutionSession().reportError(TransformedObj.takeError());
return;
}

View File

@ -89,23 +89,18 @@ RTDyldObjectLinkingLayer::~RTDyldObjectLinkingLayer() {
}
}
void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R,
std::unique_ptr<MemoryBuffer> O) {
void RTDyldObjectLinkingLayer::emit(
std::unique_ptr<MaterializationResponsibility> R,
std::unique_ptr<MemoryBuffer> O) {
assert(O && "Object must not be null");
// This method launches an asynchronous link step that will fulfill our
// materialization responsibility. We need to switch R to be heap
// allocated before that happens so it can live as long as the asynchronous
// link needs it to (i.e. it must be able to outlive this method).
auto SharedR = std::make_shared<MaterializationResponsibility>(std::move(R));
auto &ES = getExecutionSession();
auto Obj = object::ObjectFile::createObjectFile(*O);
if (!Obj) {
getExecutionSession().reportError(Obj.takeError());
SharedR->failMaterialization();
R->failMaterialization();
return;
}
@ -121,7 +116,7 @@ void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R,
continue;
} else {
ES.reportError(SymType.takeError());
R.failMaterialization();
R->failMaterialization();
return;
}
@ -129,7 +124,7 @@ void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R,
if (!SymFlagsOrErr) {
// TODO: Test this error.
ES.reportError(SymFlagsOrErr.takeError());
R.failMaterialization();
R->failMaterialization();
return;
}
@ -139,14 +134,14 @@ void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R,
InternalSymbols->insert(*SymName);
else {
ES.reportError(SymName.takeError());
R.failMaterialization();
R->failMaterialization();
return;
}
}
}
}
auto K = R.getVModuleKey();
auto K = R->getVModuleKey();
RuntimeDyld::MemoryManager *MemMgr = nullptr;
// Create a record a memory manager for this object.
@ -157,6 +152,10 @@ void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R,
MemMgr = MemMgrs.back().get();
}
// Switch to shared ownership of MR so that it can be captured by both
// lambdas below.
std::shared_ptr<MaterializationResponsibility> SharedR(std::move(R));
JITDylibSearchOrderResolver Resolver(*SharedR);
jitLinkForORC(

View File

@ -55,7 +55,7 @@ Error Speculator::addSpeculationRuntime(JITDylib &JD,
// If two modules, share the same LLVMContext, different threads must
// not access them concurrently without locking the associated LLVMContext
// this implementation follows this contract.
void IRSpeculationLayer::emit(MaterializationResponsibility R,
void IRSpeculationLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
ThreadSafeModule TSM) {
assert(TSM && "Speculation Layer received Null Module ?");
@ -127,7 +127,7 @@ void IRSpeculationLayer::emit(MaterializationResponsibility R,
assert(Mutator.GetInsertBlock()->getParent() == &Fn &&
"IR builder association mismatch?");
S.registerSymbols(internToJITSymbols(IRNames.getValue()),
&R.getTargetJITDylib());
&R->getTargetJITDylib());
}
}
}

View File

@ -35,12 +35,12 @@ TEST_F(CoreAPIsStandardTest, BasicSuccessfulLookup) {
OnCompletionRun = true;
};
std::shared_ptr<MaterializationResponsibility> FooMR;
std::unique_ptr<MaterializationResponsibility> FooMR;
cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
[&](MaterializationResponsibility R) {
FooMR = std::make_shared<MaterializationResponsibility>(std::move(R));
[&](std::unique_ptr<MaterializationResponsibility> R) {
FooMR = std::move(R);
})));
ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
@ -99,9 +99,9 @@ TEST_F(CoreAPIsStandardTest, ResolveUnrequestedSymbol) {
cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}),
[this](MaterializationResponsibility R) {
cantFail(R.notifyResolved({{Foo, FooSym}, {Bar, BarSym}}));
cantFail(R.notifyEmitted());
[this](std::unique_ptr<MaterializationResponsibility> R) {
cantFail(R->notifyResolved({{Foo, FooSym}, {Bar, BarSym}}));
cantFail(R->notifyEmitted());
})));
auto Result =
@ -116,14 +116,16 @@ TEST_F(CoreAPIsStandardTest, MaterializationSideEffctsOnlyBasic) {
// don't return until they're emitted, and that they don't appear in query
// results.
Optional<MaterializationResponsibility> FooR;
std::unique_ptr<MaterializationResponsibility> FooR;
Optional<SymbolMap> Result;
cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap(
{{Foo, JITSymbolFlags::Exported |
JITSymbolFlags::MaterializationSideEffectsOnly}}),
[&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); })));
[&](std::unique_ptr<MaterializationResponsibility> R) {
FooR = std::move(R);
})));
ES.lookup(
LookupKind::Static, makeJITDylibSearchOrder(&JD),
@ -155,7 +157,9 @@ TEST_F(CoreAPIsStandardTest, MaterializationSideEffectsOnlyFailuresPersist) {
SymbolFlagsMap(
{{Foo, JITSymbolFlags::Exported |
JITSymbolFlags::MaterializationSideEffectsOnly}}),
[&](MaterializationResponsibility R) { R.failMaterialization(); })));
[&](std::unique_ptr<MaterializationResponsibility> R) {
R->failMaterialization();
})));
EXPECT_THAT_EXPECTED(
ES.lookup(makeJITDylibSearchOrder(&JD), SymbolLookupSet({Foo})),
@ -182,10 +186,10 @@ TEST_F(CoreAPIsStandardTest, RemoveSymbolsTest) {
bool BarMaterializerDestructed = false;
cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
[this](MaterializationResponsibility R) {
[this](std::unique_ptr<MaterializationResponsibility> R) {
ADD_FAILURE() << "Unexpected materialization of \"Bar\"";
cantFail(R.notifyResolved({{Bar, BarSym}}));
cantFail(R.notifyEmitted());
cantFail(R->notifyResolved({{Bar, BarSym}}));
cantFail(R->notifyEmitted());
},
nullptr,
[&](const JITDylib &JD, const SymbolStringPtr &Name) {
@ -197,10 +201,12 @@ TEST_F(CoreAPIsStandardTest, RemoveSymbolsTest) {
// Baz will be in the materializing state initially, then
// materialized for the final removal attempt.
Optional<MaterializationResponsibility> BazR;
std::unique_ptr<MaterializationResponsibility> BazR;
cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Baz, BazSym.getFlags()}}),
[&](MaterializationResponsibility R) { BazR.emplace(std::move(R)); },
[&](std::unique_ptr<MaterializationResponsibility> R) {
BazR = std::move(R);
},
nullptr,
[](const JITDylib &JD, const SymbolStringPtr &Name) {
ADD_FAILURE() << "\"Baz\" discarded unexpectedly";
@ -297,7 +303,7 @@ TEST_F(CoreAPIsStandardTest, LookupFlagsTest) {
JITSymbolFlags::Exported | JITSymbolFlags::Weak));
auto MU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
[](MaterializationResponsibility R) {
[](std::unique_ptr<MaterializationResponsibility> R) {
llvm_unreachable("Symbol materialized on flags lookup");
});
@ -400,10 +406,10 @@ TEST_F(CoreAPIsStandardTest, TestThatReExportsDontUnnecessarilyMaterialize) {
bool BarMaterialized = false;
auto BarMU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
[&](MaterializationResponsibility R) {
[&](std::unique_ptr<MaterializationResponsibility> R) {
BarMaterialized = true;
cantFail(R.notifyResolved({{Bar, BarSym}}));
cantFail(R.notifyEmitted());
cantFail(R->notifyResolved({{Bar, BarSym}}));
cantFail(R->notifyEmitted());
});
cantFail(JD.define(BarMU));
@ -444,10 +450,12 @@ TEST_F(CoreAPIsStandardTest, TestReexportsGenerator) {
}
TEST_F(CoreAPIsStandardTest, TestTrivialCircularDependency) {
Optional<MaterializationResponsibility> FooR;
std::unique_ptr<MaterializationResponsibility> FooR;
auto FooMU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
[&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); });
[&](std::unique_ptr<MaterializationResponsibility> R) {
FooR = std::move(R);
});
cantFail(JD.define(FooMU));
@ -476,26 +484,29 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneJITDylib) {
// does not prevent any symbol from becoming 'ready' once all symbols are
// emitted.
// Create three MaterializationResponsibility objects: one for each of Foo,
// Bar and Baz. These are optional because MaterializationResponsibility
// does not have a default constructor).
Optional<MaterializationResponsibility> FooR;
Optional<MaterializationResponsibility> BarR;
Optional<MaterializationResponsibility> BazR;
std::unique_ptr<MaterializationResponsibility> FooR;
std::unique_ptr<MaterializationResponsibility> BarR;
std::unique_ptr<MaterializationResponsibility> BazR;
// Create a MaterializationUnit for each symbol that moves the
// MaterializationResponsibility into one of the locals above.
auto FooMU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
[&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); });
[&](std::unique_ptr<MaterializationResponsibility> R) {
FooR = std::move(R);
});
auto BarMU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
[&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); });
[&](std::unique_ptr<MaterializationResponsibility> R) {
BarR = std::move(R);
});
auto BazMU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Baz, BazSym.getFlags()}}),
[&](MaterializationResponsibility R) { BazR.emplace(std::move(R)); });
[&](std::unique_ptr<MaterializationResponsibility> R) {
BazR = std::move(R);
});
// Define the symbols.
cantFail(JD.define(FooMU));
@ -622,18 +633,22 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneJITDylib) {
}
TEST_F(CoreAPIsStandardTest, FailureInDependency) {
Optional<MaterializationResponsibility> FooR;
Optional<MaterializationResponsibility> BarR;
std::unique_ptr<MaterializationResponsibility> FooR;
std::unique_ptr<MaterializationResponsibility> BarR;
// Create a MaterializationUnit for each symbol that moves the
// MaterializationResponsibility into one of the locals above.
auto FooMU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
[&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); });
[&](std::unique_ptr<MaterializationResponsibility> R) {
FooR = std::move(R);
});
auto BarMU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
[&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); });
[&](std::unique_ptr<MaterializationResponsibility> R) {
BarR = std::move(R);
});
// Define the symbols.
cantFail(JD.define(FooMU));
@ -687,18 +702,22 @@ TEST_F(CoreAPIsStandardTest, FailureInDependency) {
}
TEST_F(CoreAPIsStandardTest, FailureInCircularDependency) {
Optional<MaterializationResponsibility> FooR;
Optional<MaterializationResponsibility> BarR;
std::unique_ptr<MaterializationResponsibility> FooR;
std::unique_ptr<MaterializationResponsibility> BarR;
// Create a MaterializationUnit for each symbol that moves the
// MaterializationResponsibility into one of the locals above.
auto FooMU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
[&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); });
[&](std::unique_ptr<MaterializationResponsibility> R) {
FooR = std::move(R);
});
auto BarMU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
[&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); });
[&](std::unique_ptr<MaterializationResponsibility> R) {
BarR = std::move(R);
});
// Define the symbols.
cantFail(JD.define(FooMU));
@ -753,18 +772,22 @@ TEST_F(CoreAPIsStandardTest, FailureInCircularDependency) {
}
TEST_F(CoreAPIsStandardTest, AddDependencyOnFailedSymbol) {
Optional<MaterializationResponsibility> FooR;
Optional<MaterializationResponsibility> BarR;
std::unique_ptr<MaterializationResponsibility> FooR;
std::unique_ptr<MaterializationResponsibility> BarR;
// Create a MaterializationUnit for each symbol that moves the
// MaterializationResponsibility into one of the locals above.
auto FooMU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
[&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); });
[&](std::unique_ptr<MaterializationResponsibility> R) {
FooR = std::move(R);
});
auto BarMU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
[&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); });
[&](std::unique_ptr<MaterializationResponsibility> R) {
BarR = std::move(R);
});
// Define the symbols.
cantFail(JD.define(FooMU));
@ -819,18 +842,22 @@ TEST_F(CoreAPIsStandardTest, AddDependencyOnFailedSymbol) {
}
TEST_F(CoreAPIsStandardTest, FailAfterMaterialization) {
Optional<MaterializationResponsibility> FooR;
Optional<MaterializationResponsibility> BarR;
std::unique_ptr<MaterializationResponsibility> FooR;
std::unique_ptr<MaterializationResponsibility> BarR;
// Create a MaterializationUnit for each symbol that moves the
// MaterializationResponsibility into one of the locals above.
auto FooMU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
[&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); });
[&](std::unique_ptr<MaterializationResponsibility> R) {
FooR = std::move(R);
});
auto BarMU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
[&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); });
[&](std::unique_ptr<MaterializationResponsibility> R) {
BarR = std::move(R);
});
// Define the symbols.
cantFail(JD.define(FooMU));
@ -882,9 +909,9 @@ TEST_F(CoreAPIsStandardTest, FailMaterializerWithUnqueriedSymbols) {
auto MU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap(
{{Foo, JITSymbolFlags::Exported}, {Bar, JITSymbolFlags::Exported}}),
[&](MaterializationResponsibility R) {
[&](std::unique_ptr<MaterializationResponsibility> R) {
MaterializerRun = true;
R.failMaterialization();
R->failMaterialization();
});
cantFail(JD.define(std::move(MU)));
@ -911,7 +938,7 @@ TEST_F(CoreAPIsStandardTest, DropMaterializerWhenEmpty) {
auto MU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, WeakExported}, {Bar, WeakExported}}),
[](MaterializationResponsibility R) {
[](std::unique_ptr<MaterializationResponsibility> R) {
llvm_unreachable("Unexpected call to materialize");
},
nullptr,
@ -943,10 +970,10 @@ TEST_F(CoreAPIsStandardTest, AddAndMaterializeLazySymbol) {
auto MU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}, {Bar, WeakExported}}),
[&](MaterializationResponsibility R) {
[&](std::unique_ptr<MaterializationResponsibility> R) {
assert(BarDiscarded && "Bar should have been discarded by this point");
cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}})));
cantFail(R.notifyEmitted());
cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}})));
cantFail(R->notifyEmitted());
FooMaterialized = true;
},
nullptr,
@ -985,18 +1012,18 @@ TEST_F(CoreAPIsStandardTest, TestBasicWeakSymbolMaterialization) {
bool BarMaterialized = false;
auto MU1 = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}),
[&](MaterializationResponsibility R) {
cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})));
cantFail(R.notifyEmitted());
[&](std::unique_ptr<MaterializationResponsibility> R) {
cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})));
cantFail(R->notifyEmitted());
BarMaterialized = true;
});
bool DuplicateBarDiscarded = false;
auto MU2 = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
[&](MaterializationResponsibility R) {
[&](std::unique_ptr<MaterializationResponsibility> R) {
ADD_FAILURE() << "Attempt to materialize Bar from the wrong unit";
R.failMaterialization();
R->failMaterialization();
},
nullptr,
[&](const JITDylib &JD, SymbolStringPtr Name) {
@ -1026,20 +1053,21 @@ TEST_F(CoreAPIsStandardTest, TestBasicWeakSymbolMaterialization) {
TEST_F(CoreAPIsStandardTest, DefineMaterializingSymbol) {
bool ExpectNoMoreMaterialization = false;
ES.setDispatchMaterialization([&](std::unique_ptr<MaterializationUnit> MU,
MaterializationResponsibility MR) {
if (ExpectNoMoreMaterialization)
ADD_FAILURE() << "Unexpected materialization";
MU->materialize(std::move(MR));
});
ES.setDispatchMaterialization(
[&](std::unique_ptr<MaterializationUnit> MU,
std::unique_ptr<MaterializationResponsibility> MR) {
if (ExpectNoMoreMaterialization)
ADD_FAILURE() << "Unexpected materialization";
MU->materialize(std::move(MR));
});
auto MU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
[&](MaterializationResponsibility R) {
[&](std::unique_ptr<MaterializationResponsibility> R) {
cantFail(
R.defineMaterializing(SymbolFlagsMap({{Bar, BarSym.getFlags()}})));
cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})));
cantFail(R.notifyEmitted());
R->defineMaterializing(SymbolFlagsMap({{Bar, BarSym.getFlags()}})));
cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})));
cantFail(R->notifyEmitted());
});
cantFail(JD.define(MU));
@ -1093,8 +1121,8 @@ TEST_F(CoreAPIsStandardTest, FailResolution) {
auto MU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, JITSymbolFlags::Exported | JITSymbolFlags::Weak},
{Bar, JITSymbolFlags::Exported | JITSymbolFlags::Weak}}),
[&](MaterializationResponsibility R) {
R.failMaterialization();
[&](std::unique_ptr<MaterializationResponsibility> R) {
R->failMaterialization();
});
cantFail(JD.define(MU));
@ -1129,23 +1157,23 @@ TEST_F(CoreAPIsStandardTest, FailEmissionAfterResolution) {
auto MU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}),
[&](MaterializationResponsibility R) {
cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})));
[&](std::unique_ptr<MaterializationResponsibility> R) {
cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})));
ES.lookup(
LookupKind::Static, makeJITDylibSearchOrder(&JD),
SymbolLookupSet({Baz}), SymbolState::Resolved,
[&R](Expected<SymbolMap> Result) {
[&](Expected<SymbolMap> Result) {
// Called when "baz" is resolved. We don't actually depend
// on or care about baz, but use it to trigger failure of
// this materialization before Baz has been finalized in
// order to test that error propagation is correct in this
// scenario.
cantFail(std::move(Result));
R.failMaterialization();
R->failMaterialization();
},
[&](const SymbolDependenceMap &Deps) {
R.addDependenciesForAll(Deps);
R->addDependenciesForAll(Deps);
});
});
@ -1165,7 +1193,9 @@ TEST_F(CoreAPIsStandardTest, FailAfterPartialResolution) {
// Fail materialization of bar.
auto BarMU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
[&](MaterializationResponsibility R) { R.failMaterialization(); });
[&](std::unique_ptr<MaterializationResponsibility> R) {
R->failMaterialization();
});
cantFail(JD.define(std::move(BarMU)));
@ -1185,9 +1215,9 @@ TEST_F(CoreAPIsStandardTest, FailAfterPartialResolution) {
TEST_F(CoreAPIsStandardTest, TestLookupWithUnthreadedMaterialization) {
auto MU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}),
[&](MaterializationResponsibility R) {
cantFail(R.notifyResolved({{Foo, FooSym}}));
cantFail(R.notifyEmitted());
[&](std::unique_ptr<MaterializationResponsibility> R) {
cantFail(R->notifyResolved({{Foo, FooSym}}));
cantFail(R->notifyEmitted());
});
cantFail(JD.define(MU));
@ -1204,15 +1234,14 @@ TEST_F(CoreAPIsStandardTest, TestLookupWithThreadedMaterialization) {
#if LLVM_ENABLE_THREADS
std::thread MaterializationThread;
ES.setDispatchMaterialization([&](std::unique_ptr<MaterializationUnit> MU,
MaterializationResponsibility MR) {
auto SharedMR =
std::make_shared<MaterializationResponsibility>(std::move(MR));
MaterializationThread =
std::thread([MU = std::move(MU), MR = std::move(SharedMR)] {
MU->materialize(std::move(*MR));
});
});
ES.setDispatchMaterialization(
[&](std::unique_ptr<MaterializationUnit> MU,
std::unique_ptr<MaterializationResponsibility> MR) {
MaterializationThread =
std::thread([MU = std::move(MU), MR = std::move(MR)]() mutable {
MU->materialize(std::move(MR));
});
});
cantFail(JD.define(absoluteSymbols({{Foo, FooSym}})));
@ -1238,23 +1267,23 @@ TEST_F(CoreAPIsStandardTest, TestGetRequestedSymbolsAndReplace) {
auto MU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}),
[&](MaterializationResponsibility R) {
auto Requested = R.getRequestedSymbols();
[&](std::unique_ptr<MaterializationResponsibility> R) {
auto Requested = R->getRequestedSymbols();
EXPECT_EQ(Requested.size(), 1U) << "Expected one symbol requested";
EXPECT_EQ(*Requested.begin(), Foo) << "Expected \"Foo\" requested";
auto NewMU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
[&](MaterializationResponsibility R2) {
cantFail(R2.notifyResolved(SymbolMap({{Bar, BarSym}})));
cantFail(R2.notifyEmitted());
[&](std::unique_ptr<MaterializationResponsibility> R2) {
cantFail(R2->notifyResolved(SymbolMap({{Bar, BarSym}})));
cantFail(R2->notifyEmitted());
BarMaterialized = true;
});
R.replace(std::move(NewMU));
R->replace(std::move(NewMU));
cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}})));
cantFail(R.notifyEmitted());
cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}})));
cantFail(R->notifyEmitted());
FooMaterialized = true;
});
@ -1280,13 +1309,13 @@ TEST_F(CoreAPIsStandardTest, TestGetRequestedSymbolsAndReplace) {
TEST_F(CoreAPIsStandardTest, TestMaterializationResponsibilityDelegation) {
auto MU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}),
[&](MaterializationResponsibility R) {
auto R2 = R.delegate({Bar});
[&](std::unique_ptr<MaterializationResponsibility> R) {
auto R2 = R->delegate({Bar});
cantFail(R.notifyResolved({{Foo, FooSym}}));
cantFail(R.notifyEmitted());
cantFail(R2.notifyResolved({{Bar, BarSym}}));
cantFail(R2.notifyEmitted());
cantFail(R->notifyResolved({{Foo, FooSym}}));
cantFail(R->notifyEmitted());
cantFail(R2->notifyResolved({{Bar, BarSym}}));
cantFail(R2->notifyEmitted());
});
cantFail(JD.define(MU));
@ -1309,12 +1338,11 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) {
JITSymbolFlags WeakExported = JITSymbolFlags::Exported;
WeakExported &= JITSymbolFlags::Weak;
std::unique_ptr<MaterializationResponsibility> FooResponsibility;
std::unique_ptr<MaterializationResponsibility> FooR;
auto MU = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
[&](MaterializationResponsibility R) {
FooResponsibility =
std::make_unique<MaterializationResponsibility>(std::move(R));
[&](std::unique_ptr<MaterializationResponsibility> R) {
FooR = std::move(R);
});
cantFail(JD.define(MU));
@ -1328,7 +1356,7 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) {
auto MU2 = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}),
[](MaterializationResponsibility R) {
[](std::unique_ptr<MaterializationResponsibility> R) {
llvm_unreachable("This unit should never be materialized");
});
@ -1339,8 +1367,8 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) {
consumeError(std::move(Err));
// No dependencies registered, can't fail:
cantFail(FooResponsibility->notifyResolved(SymbolMap({{Foo, FooSym}})));
cantFail(FooResponsibility->notifyEmitted());
cantFail(FooR->notifyResolved(SymbolMap({{Foo, FooSym}})));
cantFail(FooR->notifyEmitted());
}
static bool linkOrdersEqual(const std::vector<std::shared_ptr<JITDylib>> &LHS,

View File

@ -39,15 +39,15 @@ TEST_F(LazyReexportsTest, BasicLocalCallThroughManagerOperation) {
cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{DummyTarget, JITSymbolFlags::Exported}}),
[&](MaterializationResponsibility R) {
[&](std::unique_ptr<MaterializationResponsibility> R) {
DummyTargetMaterialized = true;
// No dependencies registered, can't fail.
cantFail(R.notifyResolved(
cantFail(R->notifyResolved(
{{DummyTarget,
JITEvaluatedSymbol(static_cast<JITTargetAddress>(
reinterpret_cast<uintptr_t>(&dummyTarget)),
JITSymbolFlags::Exported)}}));
cantFail(R.notifyEmitted());
cantFail(R->notifyEmitted());
})));
unsigned NotifyResolvedCount = 0;

View File

@ -86,7 +86,7 @@ private:
class SimpleMaterializationUnit : public orc::MaterializationUnit {
public:
using MaterializeFunction =
std::function<void(orc::MaterializationResponsibility)>;
std::function<void(std::unique_ptr<orc::MaterializationResponsibility>)>;
using DiscardFunction =
std::function<void(const orc::JITDylib &, orc::SymbolStringPtr)>;
using DestructorFunction = std::function<void()>;
@ -108,7 +108,8 @@ public:
StringRef getName() const override { return "<Simple>"; }
void materialize(orc::MaterializationResponsibility R) override {
void
materialize(std::unique_ptr<orc::MaterializationResponsibility> R) override {
Materialize(std::move(R));
}