}
void notifyFailed(Error Err) override {
+ for (auto &P : Layer.Plugins)
+ Err = joinErrors(std::move(Err), P->notifyFailed(*MR));
Layer.getExecutionSession().reportError(std::move(Err));
MR->failMaterialization();
}
ObjectLinkingLayer::ObjectLinkingLayer(ExecutionSession &ES,
JITLinkMemoryManager &MemMgr)
- : ObjectLayer(ES), MemMgr(MemMgr) {}
+ : ObjectLayer(ES), MemMgr(MemMgr) {
+ ES.registerResourceManager(*this);
+}
ObjectLinkingLayer::ObjectLinkingLayer(
ExecutionSession &ES, std::unique_ptr<JITLinkMemoryManager> MemMgr)
- : ObjectLayer(ES), MemMgr(*MemMgr), MemMgrOwnership(std::move(MemMgr)) {}
+ : ObjectLayer(ES), MemMgr(*MemMgr), MemMgrOwnership(std::move(MemMgr)) {
+ ES.registerResourceManager(*this);
+}
ObjectLinkingLayer::~ObjectLinkingLayer() {
- if (auto Err = removeAllModules())
- getExecutionSession().reportError(std::move(Err));
+ assert(Allocs.empty() && "Layer destroyed with resources still attached");
+ getExecutionSession().deregisterResourceManager(*this);
}
void ObjectLinkingLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
if (Err)
return Err;
- {
- std::lock_guard<std::mutex> Lock(LayerMutex);
- UntrackedAllocs.push_back(std::move(Alloc));
- }
-
- return Error::success();
+ return MR.withResourceKeyDo(
+ [&](ResourceKey K) { Allocs[K].push_back(std::move(Alloc)); });
}
-Error ObjectLinkingLayer::removeModule(VModuleKey K) {
+Error ObjectLinkingLayer::handleRemoveResources(ResourceKey K) {
+
Error Err = Error::success();
for (auto &P : Plugins)
- Err = joinErrors(std::move(Err), P->notifyRemovingModule(K));
-
- AllocPtr Alloc;
+ Err = joinErrors(std::move(Err), P->notifyRemovingResources(K));
+
+ std::vector<AllocPtr> AllocsToRemove;
+ getExecutionSession().runSessionLocked([&] {
+ auto I = Allocs.find(K);
+ if (I != Allocs.end()) {
+ std::swap(AllocsToRemove, I->second);
+ Allocs.erase(I);
+ }
+ });
- {
- std::lock_guard<std::mutex> Lock(LayerMutex);
- auto AllocItr = TrackedAllocs.find(K);
- Alloc = std::move(AllocItr->second);
- TrackedAllocs.erase(AllocItr);
+ while (!AllocsToRemove.empty()) {
+ Err = joinErrors(std::move(Err), AllocsToRemove.back()->deallocate());
+ AllocsToRemove.pop_back();
}
- assert(Alloc && "No allocation for key K");
-
- return joinErrors(std::move(Err), Alloc->deallocate());
+ return Err;
}
-Error ObjectLinkingLayer::removeAllModules() {
-
- Error Err = Error::success();
-
- for (auto &P : Plugins)
- Err = joinErrors(std::move(Err), P->notifyRemovingAllModules());
-
- std::vector<AllocPtr> Allocs;
- {
- std::lock_guard<std::mutex> Lock(LayerMutex);
- Allocs = std::move(UntrackedAllocs);
-
- for (auto &KV : TrackedAllocs)
- Allocs.push_back(std::move(KV.second));
-
- TrackedAllocs.clear();
+void ObjectLinkingLayer::handleTransferResources(ResourceKey DstKey,
+ ResourceKey SrcKey) {
+ auto I = Allocs.find(SrcKey);
+ if (I != Allocs.end()) {
+ auto &SrcAllocs = I->second;
+ auto &DstAllocs = Allocs[DstKey];
+ DstAllocs.reserve(DstAllocs.size() + SrcAllocs.size());
+ for (auto &Alloc : SrcAllocs)
+ DstAllocs.push_back(std::move(Alloc));
+
+ // Erase SrcKey entry using value rather than iterator I: I may have been
+ // invalidated when we looked up DstKey.
+ Allocs.erase(SrcKey);
}
- while (!Allocs.empty()) {
- Err = joinErrors(std::move(Err), Allocs.back()->deallocate());
- Allocs.pop_back();
- }
-
- return Err;
+ for (auto &P : Plugins)
+ P->notifyTransferringResources(DstKey, SrcKey);
}
EHFrameRegistrationPlugin::EHFrameRegistrationPlugin(
- std::unique_ptr<EHFrameRegistrar> Registrar)
- : Registrar(std::move(Registrar)) {}
+ ExecutionSession &ES, std::unique_ptr<EHFrameRegistrar> Registrar)
+ : ES(ES), Registrar(std::move(Registrar)) {}
void EHFrameRegistrationPlugin::modifyPassConfig(
MaterializationResponsibility &MR, const Triple &TT,
Error EHFrameRegistrationPlugin::notifyEmitted(
MaterializationResponsibility &MR) {
- std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
-
- auto EHFrameRangeItr = InProcessLinks.find(&MR);
- if (EHFrameRangeItr == InProcessLinks.end())
- return Error::success();
-
- auto EHFrameRange = EHFrameRangeItr->second;
- assert(EHFrameRange.Addr &&
- "eh-frame addr to register can not be null");
-
- InProcessLinks.erase(EHFrameRangeItr);
- if (auto Key = MR.getVModuleKey())
- TrackedEHFrameRanges[Key] = EHFrameRange;
- else
- UntrackedEHFrameRanges.push_back(EHFrameRange);
- return Registrar->registerEHFrames(EHFrameRange.Addr, EHFrameRange.Size);
-}
-
-Error EHFrameRegistrationPlugin::notifyRemovingModule(VModuleKey K) {
- std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
+ EHFrameRange EmittedRange;
+ {
+ std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
- auto EHFrameRangeItr = TrackedEHFrameRanges.find(K);
- if (EHFrameRangeItr == TrackedEHFrameRanges.end())
- return Error::success();
+ auto EHFrameRangeItr = InProcessLinks.find(&MR);
+ if (EHFrameRangeItr == InProcessLinks.end())
+ return Error::success();
- auto EHFrameRange = EHFrameRangeItr->second;
- assert(EHFrameRange.Addr && "Tracked eh-frame range must not be null");
+ EmittedRange = EHFrameRangeItr->second;
+ assert(EmittedRange.Addr && "eh-frame addr to register can not be null");
+ InProcessLinks.erase(EHFrameRangeItr);
+ }
- TrackedEHFrameRanges.erase(EHFrameRangeItr);
+ if (auto Err = MR.withResourceKeyDo(
+ [&](ResourceKey K) { EHFrameRanges[K].push_back(EmittedRange); }))
+ return Err;
- return Registrar->deregisterEHFrames(EHFrameRange.Addr, EHFrameRange.Size);
+ return Registrar->registerEHFrames(EmittedRange.Addr, EmittedRange.Size);
}
-Error EHFrameRegistrationPlugin::notifyRemovingAllModules() {
+Error EHFrameRegistrationPlugin::notifyFailed(
+ MaterializationResponsibility &MR) {
std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
+ InProcessLinks.erase(&MR);
+ return Error::success();
+}
- std::vector<EHFrameRange> EHFrameRanges =
- std::move(UntrackedEHFrameRanges);
- EHFrameRanges.reserve(EHFrameRanges.size() + TrackedEHFrameRanges.size());
-
- for (auto &KV : TrackedEHFrameRanges)
- EHFrameRanges.push_back(KV.second);
+Error EHFrameRegistrationPlugin::notifyRemovingResources(ResourceKey K) {
+ std::vector<EHFrameRange> RangesToRemove;
- TrackedEHFrameRanges.clear();
+ ES.runSessionLocked([&] {
+ auto I = EHFrameRanges.find(K);
+ if (I != EHFrameRanges.end()) {
+ RangesToRemove = std::move(I->second);
+ EHFrameRanges.erase(I);
+ }
+ });
Error Err = Error::success();
-
- while (!EHFrameRanges.empty()) {
- auto EHFrameRange = EHFrameRanges.back();
- assert(EHFrameRange.Addr && "Untracked eh-frame range must not be null");
- EHFrameRanges.pop_back();
- Err = joinErrors(std::move(Err), Registrar->deregisterEHFrames(
- EHFrameRange.Addr, EHFrameRange.Size));
+ while (!RangesToRemove.empty()) {
+ auto RangeToRemove = RangesToRemove.back();
+ RangesToRemove.pop_back();
+ assert(RangeToRemove.Addr && "Untracked eh-frame range must not be null");
+ Err = joinErrors(
+ std::move(Err),
+ Registrar->deregisterEHFrames(RangeToRemove.Addr, RangeToRemove.Size));
}
return Err;
}
+void EHFrameRegistrationPlugin::notifyTransferringResources(
+ ResourceKey DstKey, ResourceKey SrcKey) {
+ auto SI = EHFrameRanges.find(SrcKey);
+ if (SI != EHFrameRanges.end()) {
+ auto &SrcRanges = SI->second;
+ auto &DstRanges = EHFrameRanges[DstKey];
+ DstRanges.reserve(DstRanges.size() + SrcRanges.size());
+ for (auto &SrcRange : SrcRanges)
+ DstRanges.push_back(std::move(SrcRange));
+ EHFrameRanges.erase(SI);
+ }
+}
+
} // End namespace orc.
} // End namespace llvm.