Skip to content

Commit c32a4f8

Browse files
committed
[ORC] Allow removal of ObjectLinkingLayer Plugins.
This adds a removePlugin operation to ObjectLinkingLayer. The removal of a plugin will be visible in all links started after the removal (ongoing links started before the removal will still use the removed plugin). Coding my way home: 17.56037S, 149.61118W
1 parent a015f01 commit c32a4f8

File tree

2 files changed

+90
-1
lines changed

2 files changed

+90
-1
lines changed

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,26 @@ class ObjectLinkingLayer : public RTTIExtends<ObjectLinkingLayer, ObjectLayer>,
121121
this->ReturnObjectBuffer = std::move(ReturnObjectBuffer);
122122
}
123123

124-
/// Add a pass-config modifier.
124+
/// Add a plugin.
125125
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;
129129
}
130130

131+
/// Remove a plugin. This remove applies only to subsequent links (links
132+
/// already underway will continue to use the plugin), and does not of itself
133+
/// destroy the plugin -- destruction will happen once all shared pointers
134+
/// (including those held by in-progress links) are destroyed.
135+
void removePlugin(Plugin &P) {
136+
std::lock_guard<std::mutex> Lock(LayerMutex);
137+
auto I = llvm::find_if(Plugins, [&](const std::shared_ptr<Plugin> &Elem) {
138+
return Elem.get() == &P;
139+
});
140+
assert(I != Plugins.end() && "Plugin not present");
141+
Plugins.erase(I);
142+
}
143+
131144
/// Add a LinkGraph to the JITDylib targeted by the given tracker.
132145
Error add(ResourceTrackerSP, std::unique_ptr<jitlink::LinkGraph> G);
133146

llvm/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,82 @@ TEST_F(ObjectLinkingLayerTest, HandleErrorDuringPostAllocationPass) {
178178
EXPECT_THAT_EXPECTED(ES.lookup(&JD, "_anchor"), Failed());
179179
}
180180

181+
TEST_F(ObjectLinkingLayerTest, AddAndRemovePlugins) {
182+
class TestPlugin : public ObjectLinkingLayer::Plugin {
183+
public:
184+
TestPlugin(size_t &ActivationCount, bool &PluginDestroyed)
185+
: ActivationCount(ActivationCount), PluginDestroyed(PluginDestroyed) {}
186+
187+
~TestPlugin() { PluginDestroyed = true; }
188+
189+
void modifyPassConfig(MaterializationResponsibility &MR,
190+
jitlink::LinkGraph &G,
191+
jitlink::PassConfiguration &Config) override {
192+
++ActivationCount;
193+
}
194+
195+
Error notifyFailed(MaterializationResponsibility &MR) override {
196+
ADD_FAILURE() << "TestPlugin::notifyFailed called unexpectedly";
197+
return Error::success();
198+
}
199+
200+
Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override {
201+
return Error::success();
202+
}
203+
204+
void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,
205+
ResourceKey SrcKey) override {}
206+
207+
private:
208+
size_t &ActivationCount;
209+
bool &PluginDestroyed;
210+
};
211+
212+
size_t ActivationCount = 0;
213+
bool PluginDestroyed = false;
214+
215+
auto P = std::make_shared<TestPlugin>(ActivationCount, PluginDestroyed);
216+
217+
ObjLinkingLayer.addPlugin(P);
218+
219+
{
220+
auto G1 = std::make_unique<LinkGraph>("G1", Triple("x86_64-apple-darwin"),
221+
8, llvm::endianness::little,
222+
x86_64::getEdgeKindName);
223+
224+
auto &DataSec = G1->createSection("__data", MemProt::Read | MemProt::Write);
225+
auto &DataBlock = G1->createContentBlock(DataSec, BlockContent,
226+
orc::ExecutorAddr(0x1000), 8, 0);
227+
G1->addDefinedSymbol(DataBlock, 4, "_anchor1", 4, Linkage::Weak,
228+
Scope::Default, false, true);
229+
230+
EXPECT_THAT_ERROR(ObjLinkingLayer.add(JD, std::move(G1)), Succeeded());
231+
EXPECT_THAT_EXPECTED(ES.lookup(&JD, "_anchor1"), Succeeded());
232+
EXPECT_EQ(ActivationCount, 1U);
233+
}
234+
235+
ObjLinkingLayer.removePlugin(*P);
236+
237+
{
238+
auto G2 = std::make_unique<LinkGraph>("G2", Triple("x86_64-apple-darwin"),
239+
8, llvm::endianness::little,
240+
x86_64::getEdgeKindName);
241+
242+
auto &DataSec = G2->createSection("__data", MemProt::Read | MemProt::Write);
243+
auto &DataBlock = G2->createContentBlock(DataSec, BlockContent,
244+
orc::ExecutorAddr(0x1000), 8, 0);
245+
G2->addDefinedSymbol(DataBlock, 4, "_anchor2", 4, Linkage::Weak,
246+
Scope::Default, false, true);
247+
248+
EXPECT_THAT_ERROR(ObjLinkingLayer.add(JD, std::move(G2)), Succeeded());
249+
EXPECT_THAT_EXPECTED(ES.lookup(&JD, "_anchor2"), Succeeded());
250+
EXPECT_EQ(ActivationCount, 1U);
251+
}
252+
253+
P.reset();
254+
EXPECT_TRUE(PluginDestroyed);
255+
}
256+
181257
TEST(ObjectLinkingLayerSearchGeneratorTest, AbsoluteSymbolsObjectLayer) {
182258
class TestEPC : public UnsupportedExecutorProcessControl {
183259
public:

0 commit comments

Comments
 (0)