Skip to content

Commit a9fdf37

Browse files
committed
[ORC] Add a 'plugin' interface to ObjectLinkingLayer for events/configuration.
ObjectLinkingLayer::Plugin provides event notifications when objects are loaded, emitted, and removed. It also provides a modifyPassConfig callback that allows plugins to modify the JITLink pass configuration. This patch moves eh-frame registration into its own plugin, and teaches llvm-jitlink to only add that plugin when performing execution runs on non-Windows platforms. This should allow us to re-enable the test case that was removed in r359198. llvm-svn: 359357
1 parent 353f593 commit a9fdf37

File tree

6 files changed

+238
-99
lines changed

6 files changed

+238
-99
lines changed

Diff for: llvm/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,17 @@ Error registerEHFrameSection(const void *EHFrameSectionAddr);
2727
/// Deregisters all FDEs in the given eh-frame section with the current process.
2828
Error deregisterEHFrameSection(const void *EHFrameSectionAddr);
2929

30+
using StoreFrameAddressFunction = std::function<void(JITTargetAddress)>;
31+
3032
/// Creates a pass that records the address of the EH frame section. If no
3133
/// eh-frame section is found, it will set EHFrameAddr to zero.
3234
///
3335
/// Authors of JITLinkContexts can use this function to register a post-fixup
3436
/// pass that records the address of the eh-frame section. This address can
3537
/// be used after finalization to register and deregister the frame.
36-
AtomGraphPassFunction createEHFrameRecorderPass(const Triple &TT,
37-
JITTargetAddress &EHFrameAddr);
38+
AtomGraphPassFunction
39+
createEHFrameRecorderPass(const Triple &TT,
40+
StoreFrameAddressFunction StoreFrameAddress);
3841

3942
} // end namespace jitlink
4043
} // end namespace llvm

Diff for: llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h

+58-33
Original file line numberDiff line numberDiff line change
@@ -41,27 +41,48 @@ namespace orc {
4141

4242
class ObjectLinkingLayerJITLinkContext;
4343

44+
/// An ObjectLayer implementation built on JITLink.
45+
///
46+
/// Clients can use this class to add relocatable object files to an
47+
/// ExecutionSession, and it typically serves as the base layer (underneath
48+
/// a compiling layer like IRCompileLayer) for the rest of the JIT.
4449
class ObjectLinkingLayer : public ObjectLayer {
4550
friend class ObjectLinkingLayerJITLinkContext;
4651

4752
public:
48-
/// Function object for receiving object-loaded notifications.
49-
using NotifyLoadedFunction = std::function<void(VModuleKey)>;
53+
/// Plugin instances can be added to the ObjectLinkingLayer to receive
54+
/// callbacks when code is loaded or emitted, and when JITLink is being
55+
/// configured.
56+
class Plugin {
57+
public:
58+
virtual ~Plugin();
59+
virtual void modifyPassConfig(MaterializationResponsibility &MR,
60+
const Triple &TT,
61+
jitlink::PassConfiguration &Config) {}
62+
virtual void notifyLoaded(MaterializationResponsibility &MR) {}
63+
virtual Error notifyEmitted(MaterializationResponsibility &MR) {
64+
return Error::success();
65+
}
66+
virtual Error notifyRemovingModule(VModuleKey K) {
67+
return Error::success();
68+
}
69+
virtual Error notifyRemovingAllModules() { return Error::success(); }
70+
};
5071

51-
/// Function object for receiving finalization notifications.
52-
using NotifyEmittedFunction = std::function<void(VModuleKey)>;
72+
/// Construct an ObjectLinkingLayer with the given NotifyLoaded,
73+
/// and NotifyEmitted functors.
74+
ObjectLinkingLayer(ExecutionSession &ES,
75+
jitlink::JITLinkMemoryManager &MemMgr);
5376

54-
/// Function object for modifying PassConfiguration objects.
55-
using ModifyPassConfigFunction =
56-
std::function<void(const Triple &TT, jitlink::PassConfiguration &Config)>;
77+
/// Destruct an ObjectLinkingLayer.
78+
~ObjectLinkingLayer();
5779

58-
/// Construct an ObjectLinkingLayer with the given NotifyLoaded,
59-
/// and NotifyEmitted functors.
60-
ObjectLinkingLayer(
61-
ExecutionSession &ES, jitlink::JITLinkMemoryManager &MemMgr,
62-
NotifyLoadedFunction NotifyLoaded = NotifyLoadedFunction(),
63-
NotifyEmittedFunction NotifyEmitted = NotifyEmittedFunction(),
64-
ModifyPassConfigFunction ModifyPassConfig = ModifyPassConfigFunction());
80+
/// Add a pass-config modifier.
81+
ObjectLinkingLayer &addPlugin(std::unique_ptr<Plugin> P) {
82+
std::lock_guard<std::mutex> Lock(LayerMutex);
83+
Plugins.push_back(std::move(P));
84+
return *this;
85+
}
6586

6687
/// Emit the object.
6788
void emit(MaterializationResponsibility R,
@@ -101,31 +122,35 @@ class ObjectLinkingLayer : public ObjectLayer {
101122
private:
102123
using AllocPtr = std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation>;
103124

104-
class ObjectResources {
105-
public:
106-
ObjectResources() = default;
107-
ObjectResources(AllocPtr Alloc, JITTargetAddress EHFrameAddr);
108-
ObjectResources(ObjectResources &&Other);
109-
ObjectResources &operator=(ObjectResources &&Other);
110-
~ObjectResources();
111-
112-
private:
113-
AllocPtr Alloc;
114-
JITTargetAddress EHFrameAddr = 0;
115-
};
125+
void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
126+
jitlink::PassConfiguration &PassConfig);
127+
void notifyLoaded(MaterializationResponsibility &MR);
128+
Error notifyEmitted(MaterializationResponsibility &MR, AllocPtr Alloc);
116129

117-
void notifyFinalized(ObjectResources OR) {
118-
ObjResources.push_back(std::move(OR));
119-
}
130+
Error removeModule(VModuleKey K);
131+
Error removeAllModules();
120132

121133
mutable std::mutex LayerMutex;
122134
jitlink::JITLinkMemoryManager &MemMgr;
123-
NotifyLoadedFunction NotifyLoaded;
124-
NotifyEmittedFunction NotifyEmitted;
125-
ModifyPassConfigFunction ModifyPassConfig;
126135
bool OverrideObjectFlags = false;
127136
bool AutoClaimObjectSymbols = false;
128-
std::vector<ObjectResources> ObjResources;
137+
DenseMap<VModuleKey, AllocPtr> TrackedAllocs;
138+
std::vector<AllocPtr> UntrackedAllocs;
139+
std::vector<std::unique_ptr<Plugin>> Plugins;
140+
};
141+
142+
class LocalEHFrameRegistrationPlugin : public ObjectLinkingLayer::Plugin {
143+
public:
144+
Error notifyEmitted(MaterializationResponsibility &MR) override;
145+
void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
146+
jitlink::PassConfiguration &PassConfig) override;
147+
Error notifyRemovingModule(VModuleKey K) override;
148+
Error notifyRemovingAllModules() override;
149+
150+
private:
151+
DenseMap<MaterializationResponsibility *, const void *> InProcessLinks;
152+
DenseMap<VModuleKey, const void *> TrackedEHFrameAddrs;
153+
std::vector<const void *> UntrackedEHFrameAddrs;
129154
};
130155

131156
} // end namespace orc

Diff for: llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -507,16 +507,17 @@ Error deregisterEHFrameSection(const void *EHFrameSectionAddr) {
507507
#endif
508508
}
509509

510-
AtomGraphPassFunction createEHFrameRecorderPass(const Triple &TT,
511-
JITTargetAddress &EHFrameAddr) {
510+
AtomGraphPassFunction
511+
createEHFrameRecorderPass(const Triple &TT,
512+
StoreFrameAddressFunction StoreFrameAddress) {
512513
const char *EHFrameSectionName = nullptr;
513514
if (TT.getObjectFormat() == Triple::MachO)
514515
EHFrameSectionName = "__eh_frame";
515516
else
516517
EHFrameSectionName = ".eh_frame";
517518

518519
auto RecordEHFrame = [EHFrameSectionName,
519-
&EHFrameAddr](AtomGraph &G) -> Error {
520+
StoreFrameAddress](AtomGraph &G) -> Error {
520521
// Search for a non-empty eh-frame and record the address of the first atom
521522
// in it.
522523
JITTargetAddress Addr = 0;
@@ -529,7 +530,7 @@ AtomGraphPassFunction createEHFrameRecorderPass(const Triple &TT,
529530
break;
530531
}
531532

532-
EHFrameAddr = Addr;
533+
StoreFrameAddress(Addr);
533534
return Error::success();
534535
};
535536

0 commit comments

Comments
 (0)