Skip to content

Commit 7565b20

Browse files
committed
[ORC] Switch ObjectLinkingLayer::Plugins to shared ownership, copy pipeline.
Previously ObjectLinkingLayer held unique ownership of Plugins, and links always used the Layer's plugin list at each step. This can cause problems if plugins are added while links are in progress however, as the newly added plugin may receive only some of the callbacks for links that are already running. In this patch each link gets its own copy of the pipeline that remains consistent throughout the link's lifetime, and it is guaranteed that Plugin objects (now with shared ownership) will remain valid until the link completes. Coding my way home: 9.80469S, 139.03167W
1 parent 9a9cff1 commit 7565b20

File tree

2 files changed

+42
-42
lines changed

2 files changed

+42
-42
lines changed

llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ class ObjectLinkingLayer : public RTTIExtends<ObjectLinkingLayer, ObjectLayer>,
122122
}
123123

124124
/// Add a pass-config modifier.
125-
ObjectLinkingLayer &addPlugin(std::unique_ptr<Plugin> P) {
125+
ObjectLinkingLayer &addPlugin(std::shared_ptr<Plugin> P) {
126126
std::lock_guard<std::mutex> Lock(LayerMutex);
127127
Plugins.push_back(std::move(P));
128128
return *this;
@@ -181,11 +181,8 @@ class ObjectLinkingLayer : public RTTIExtends<ObjectLinkingLayer, ObjectLayer>,
181181
private:
182182
using FinalizedAlloc = jitlink::JITLinkMemoryManager::FinalizedAlloc;
183183

184-
void modifyPassConfig(MaterializationResponsibility &MR,
185-
jitlink::LinkGraph &G,
186-
jitlink::PassConfiguration &PassConfig);
187-
void notifyLoaded(MaterializationResponsibility &MR);
188-
Error notifyEmitted(MaterializationResponsibility &MR, FinalizedAlloc FA);
184+
Error recordFinalizedAlloc(MaterializationResponsibility &MR,
185+
FinalizedAlloc FA);
189186

190187
Error handleRemoveResources(JITDylib &JD, ResourceKey K) override;
191188
void handleTransferResources(JITDylib &JD, ResourceKey DstKey,
@@ -198,7 +195,7 @@ class ObjectLinkingLayer : public RTTIExtends<ObjectLinkingLayer, ObjectLayer>,
198195
bool AutoClaimObjectSymbols = false;
199196
ReturnObjectBufferFunction ReturnObjectBuffer;
200197
DenseMap<ResourceKey, std::vector<FinalizedAlloc>> Allocs;
201-
std::vector<std::unique_ptr<Plugin>> Plugins;
198+
std::vector<std::shared_ptr<Plugin>> Plugins;
202199
};
203200

204201
class EHFrameRegistrationPlugin : public ObjectLinkingLayer::Plugin {

llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,10 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
156156
std::unique_ptr<MaterializationResponsibility> MR,
157157
std::unique_ptr<MemoryBuffer> ObjBuffer)
158158
: JITLinkContext(&MR->getTargetJITDylib()), Layer(Layer),
159-
MR(std::move(MR)), ObjBuffer(std::move(ObjBuffer)) {}
159+
MR(std::move(MR)), ObjBuffer(std::move(ObjBuffer)) {
160+
std::lock_guard<std::mutex> Lock(Layer.LayerMutex);
161+
Plugins = Layer.Plugins;
162+
}
160163

161164
~ObjectLinkingLayerJITLinkContext() {
162165
// If there is an object buffer return function then use it to
@@ -168,14 +171,14 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
168171
JITLinkMemoryManager &getMemoryManager() override { return Layer.MemMgr; }
169172

170173
void notifyMaterializing(LinkGraph &G) {
171-
for (auto &P : Layer.Plugins)
174+
for (auto &P : Plugins)
172175
P->notifyMaterializing(*MR, G, *this,
173176
ObjBuffer ? ObjBuffer->getMemBufferRef()
174177
: MemoryBufferRef());
175178
}
176179

177180
void notifyFailed(Error Err) override {
178-
for (auto &P : Layer.Plugins)
181+
for (auto &P : Plugins)
179182
Err = joinErrors(std::move(Err), P->notifyFailed(*MR));
180183
Layer.getExecutionSession().reportError(std::move(Err));
181184
MR->failMaterialization();
@@ -317,12 +320,12 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
317320
if (auto Err = MR->notifyResolved(InternedResult))
318321
return Err;
319322

320-
Layer.notifyLoaded(*MR);
323+
notifyLoaded();
321324
return Error::success();
322325
}
323326

324327
void notifyFinalized(JITLinkMemoryManager::FinalizedAlloc A) override {
325-
if (auto Err = Layer.notifyEmitted(*MR, std::move(A))) {
328+
if (auto Err = notifyEmitted(std::move(A))) {
326329
Layer.getExecutionSession().reportError(std::move(Err));
327330
MR->failMaterialization();
328331
return;
@@ -344,14 +347,38 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
344347
return claimOrExternalizeWeakAndCommonSymbols(G);
345348
});
346349

347-
Layer.modifyPassConfig(*MR, LG, Config);
350+
for (auto &P : Plugins)
351+
P->modifyPassConfig(*MR, LG, Config);
348352

349353
Config.PreFixupPasses.push_back(
350354
[this](LinkGraph &G) { return registerDependencies(G); });
351355

352356
return Error::success();
353357
}
354358

359+
void notifyLoaded() {
360+
for (auto &P : Plugins)
361+
P->notifyLoaded(*MR);
362+
}
363+
364+
Error notifyEmitted(jitlink::JITLinkMemoryManager::FinalizedAlloc FA) {
365+
Error Err = Error::success();
366+
for (auto &P : Plugins)
367+
Err = joinErrors(std::move(Err), P->notifyEmitted(*MR));
368+
369+
if (Err) {
370+
if (FA)
371+
Err =
372+
joinErrors(std::move(Err), Layer.MemMgr.deallocate(std::move(FA)));
373+
return Err;
374+
}
375+
376+
if (FA)
377+
return Layer.recordFinalizedAlloc(*MR, std::move(FA));
378+
379+
return Error::success();
380+
}
381+
355382
private:
356383
// Symbol name dependencies:
357384
// Internal: Defined in this graph.
@@ -522,7 +549,7 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
522549

523550
SymbolDependenceGroup SynthSDG;
524551

525-
for (auto &P : Layer.Plugins) {
552+
for (auto &P : Plugins) {
526553
auto SynthDeps = P->getSyntheticSymbolDependencies(*MR);
527554
if (SynthDeps.empty())
528555
continue;
@@ -636,6 +663,7 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
636663
}
637664

638665
ObjectLinkingLayer &Layer;
666+
std::vector<std::shared_ptr<ObjectLinkingLayer::Plugin>> Plugins;
639667
std::unique_ptr<MaterializationResponsibility> MR;
640668
std::unique_ptr<MemoryBuffer> ObjBuffer;
641669
DenseMap<Block *, SymbolNameSet> ExternalBlockDeps;
@@ -702,34 +730,9 @@ void ObjectLinkingLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
702730
link(std::move(G), std::move(Ctx));
703731
}
704732

705-
void ObjectLinkingLayer::modifyPassConfig(MaterializationResponsibility &MR,
706-
LinkGraph &G,
707-
PassConfiguration &PassConfig) {
708-
for (auto &P : Plugins)
709-
P->modifyPassConfig(MR, G, PassConfig);
710-
}
711-
712-
void ObjectLinkingLayer::notifyLoaded(MaterializationResponsibility &MR) {
713-
for (auto &P : Plugins)
714-
P->notifyLoaded(MR);
715-
}
716-
717-
Error ObjectLinkingLayer::notifyEmitted(MaterializationResponsibility &MR,
718-
FinalizedAlloc FA) {
719-
Error Err = Error::success();
720-
for (auto &P : Plugins)
721-
Err = joinErrors(std::move(Err), P->notifyEmitted(MR));
722-
723-
if (Err) {
724-
if (FA)
725-
Err = joinErrors(std::move(Err), MemMgr.deallocate(std::move(FA)));
726-
return Err;
727-
}
728-
729-
if (!FA)
730-
return Error::success();
731-
732-
Err = MR.withResourceKeyDo(
733+
Error ObjectLinkingLayer::recordFinalizedAlloc(
734+
MaterializationResponsibility &MR, FinalizedAlloc FA) {
735+
auto Err = MR.withResourceKeyDo(
733736
[&](ResourceKey K) { Allocs[K].push_back(std::move(FA)); });
734737

735738
if (Err)

0 commit comments

Comments
 (0)