Skip to content

Commit 9667912

Browse files
committed
[ORC] Remove EHFrameRegistrar, use allocation actions for eh-frame registration.
This simplifies resource management, and should improve performance for most use cases.
1 parent 666540c commit 9667912

File tree

9 files changed

+71
-294
lines changed

9 files changed

+71
-294
lines changed

llvm/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -83,35 +83,9 @@ class EHFrameCFIBlockInspector {
8383
};
8484
};
8585

86-
/// Supports registration/deregistration of EH-frames in a target process.
87-
class EHFrameRegistrar {
88-
public:
89-
virtual ~EHFrameRegistrar();
90-
virtual Error registerEHFrames(orc::ExecutorAddrRange EHFrameSection) = 0;
91-
virtual Error deregisterEHFrames(orc::ExecutorAddrRange EHFrameSection) = 0;
92-
};
93-
94-
/// Registers / Deregisters EH-frames in the current process.
95-
class InProcessEHFrameRegistrar final : public EHFrameRegistrar {
96-
public:
97-
Error registerEHFrames(orc::ExecutorAddrRange EHFrameSection) override;
98-
99-
Error deregisterEHFrames(orc::ExecutorAddrRange EHFrameSection) override;
100-
};
101-
102-
using StoreFrameRangeFunction = std::function<void(
103-
orc::ExecutorAddr EHFrameSectionAddr, size_t EHFrameSectionSize)>;
104-
105-
/// Creates a pass that records the address and size of the EH frame section.
106-
/// If no eh-frame section is found then the address and size will both be given
107-
/// as zero.
108-
///
109-
/// Authors of JITLinkContexts can use this function to register a post-fixup
110-
/// pass that records the range of the eh-frame section. This range can
111-
/// be used after finalization to register and deregister the frame.
112-
LinkGraphPassFunction
113-
createEHFrameRecorderPass(const Triple &TT,
114-
StoreFrameRangeFunction StoreFrameRange);
86+
/// Returns a pointer to the DWARF eh-frame section if the graph contains a
87+
/// non-empty one, otherwise returns null.
88+
Section *getEHFrameSection(LinkGraph &G);
11589

11690
} // end namespace jitlink
11791
} // end namespace llvm

llvm/include/llvm/ExecutionEngine/Orc/EHFrameRegistrationPlugin.h

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,37 +19,38 @@
1919
#include <mutex>
2020
#include <vector>
2121

22-
namespace llvm {
23-
24-
namespace jitlink {
25-
class EHFrameRegistrar;
26-
} // namespace jitlink
27-
28-
namespace orc {
22+
namespace llvm::orc {
2923

24+
/// Adds AllocationActions to register and deregister eh-frame sections in the
25+
/// absence of native Platform support.
3026
class EHFrameRegistrationPlugin : public LinkGraphLinkingLayer::Plugin {
3127
public:
32-
EHFrameRegistrationPlugin(
33-
ExecutionSession &ES,
34-
std::unique_ptr<jitlink::EHFrameRegistrar> Registrar);
28+
static Expected<std::unique_ptr<EHFrameRegistrationPlugin>>
29+
Create(ExecutionSession &ES);
30+
31+
EHFrameRegistrationPlugin(ExecutionSession &ES, ExecutorAddr RegisterEHFrame,
32+
ExecutorAddr DeregisterEHFrame)
33+
: ES(ES), RegisterEHFrame(RegisterEHFrame),
34+
DeregisterEHFrame(DeregisterEHFrame) {}
35+
3536
void modifyPassConfig(MaterializationResponsibility &MR,
3637
jitlink::LinkGraph &G,
3738
jitlink::PassConfiguration &PassConfig) override;
38-
Error notifyEmitted(MaterializationResponsibility &MR) override;
39-
Error notifyFailed(MaterializationResponsibility &MR) override;
40-
Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override;
39+
Error notifyFailed(MaterializationResponsibility &MR) override {
40+
return Error::success();
41+
}
42+
Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override {
43+
return Error::success();
44+
}
4145
void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,
42-
ResourceKey SrcKey) override;
46+
ResourceKey SrcKey) override {}
4347

4448
private:
45-
std::mutex EHFramePluginMutex;
4649
ExecutionSession &ES;
47-
std::unique_ptr<jitlink::EHFrameRegistrar> Registrar;
48-
DenseMap<MaterializationResponsibility *, ExecutorAddrRange> InProcessLinks;
49-
DenseMap<ResourceKey, std::vector<ExecutorAddrRange>> EHFrameRanges;
50+
ExecutorAddr RegisterEHFrame;
51+
ExecutorAddr DeregisterEHFrame;
5052
};
5153

52-
} // end namespace orc
53-
} // end namespace llvm
54+
} // namespace llvm::orc
5455

5556
#endif // LLVM_EXECUTIONENGINE_ORC_EHFRAMEREGISTRATIONPLUGIN_H

llvm/include/llvm/ExecutionEngine/Orc/EPCEHFrameRegistrar.h

Lines changed: 0 additions & 58 deletions
This file was deleted.

llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp

Lines changed: 13 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -639,20 +639,6 @@ Error EHFrameNullTerminator::operator()(LinkGraph &G) {
639639
return Error::success();
640640
}
641641

642-
EHFrameRegistrar::~EHFrameRegistrar() = default;
643-
644-
Error InProcessEHFrameRegistrar::registerEHFrames(
645-
orc::ExecutorAddrRange EHFrameSection) {
646-
return orc::registerEHFrameSection(EHFrameSection.Start.toPtr<void *>(),
647-
EHFrameSection.size());
648-
}
649-
650-
Error InProcessEHFrameRegistrar::deregisterEHFrames(
651-
orc::ExecutorAddrRange EHFrameSection) {
652-
return orc::deregisterEHFrameSection(EHFrameSection.Start.toPtr<void *>(),
653-
EHFrameSection.size());
654-
}
655-
656642
EHFrameCFIBlockInspector EHFrameCFIBlockInspector::FromEdgeScan(Block &B) {
657643
if (B.edges_empty())
658644
return EHFrameCFIBlockInspector(nullptr);
@@ -678,36 +664,24 @@ EHFrameCFIBlockInspector::EHFrameCFIBlockInspector(Edge &CIEEdge,
678664
Edge *LSDAEdge)
679665
: CIEEdge(&CIEEdge), PCBeginEdge(&PCBeginEdge), LSDAEdge(LSDAEdge) {}
680666

681-
LinkGraphPassFunction
682-
createEHFrameRecorderPass(const Triple &TT,
683-
StoreFrameRangeFunction StoreRangeAddress) {
667+
Section *getEHFrameSection(LinkGraph &G) {
684668
const char *EHFrameSectionName = nullptr;
685-
if (TT.getObjectFormat() == Triple::MachO)
669+
switch (G.getTargetTriple().getObjectFormat()) {
670+
case Triple::MachO:
686671
EHFrameSectionName = "__TEXT,__eh_frame";
687-
else
672+
break;
673+
case Triple::ELF:
688674
EHFrameSectionName = ".eh_frame";
675+
break;
676+
default:
677+
return nullptr;
678+
}
689679

690-
auto RecordEHFrame =
691-
[EHFrameSectionName,
692-
StoreFrameRange = std::move(StoreRangeAddress)](LinkGraph &G) -> Error {
693-
// Search for a non-empty eh-frame and record the address of the first
694-
// symbol in it.
695-
orc::ExecutorAddr Addr;
696-
size_t Size = 0;
697-
if (auto *S = G.findSectionByName(EHFrameSectionName)) {
698-
auto R = SectionRange(*S);
699-
Addr = R.getStart();
700-
Size = R.getSize();
701-
}
702-
if (!Addr && Size != 0)
703-
return make_error<JITLinkError>(
704-
StringRef(EHFrameSectionName) +
705-
" section can not have zero address with non-zero size");
706-
StoreFrameRange(Addr, Size);
707-
return Error::success();
708-
};
680+
if (auto *S = G.findSectionByName(EHFrameSectionName))
681+
if (!S->empty())
682+
return S;
709683

710-
return RecordEHFrame;
684+
return nullptr;
711685
}
712686

713687
} // end namespace jitlink

llvm/lib/ExecutionEngine/Orc/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ add_llvm_component_library(LLVMOrcJIT
1818
EHFrameRegistrationPlugin.cpp
1919
EPCDynamicLibrarySearchGenerator.cpp
2020
EPCDebugObjectRegistrar.cpp
21-
EPCEHFrameRegistrar.cpp
2221
EPCGenericDylibManager.cpp
2322
EPCGenericJITLinkMemoryManager.cpp
2423
EPCGenericRTDyldMemoryManager.cpp

llvm/lib/ExecutionEngine/Orc/EHFrameRegistrationPlugin.cpp

Lines changed: 29 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,34 @@
1010

1111
#include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h"
1212
#include "llvm/ExecutionEngine/Orc/Shared/MachOObjectFormat.h"
13+
#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
1314

1415
#define DEBUG_TYPE "orc"
1516

1617
using namespace llvm::jitlink;
1718

1819
namespace llvm::orc {
1920

20-
EHFrameRegistrationPlugin::EHFrameRegistrationPlugin(
21-
ExecutionSession &ES, std::unique_ptr<EHFrameRegistrar> Registrar)
22-
: ES(ES), Registrar(std::move(Registrar)) {}
21+
Expected<std::unique_ptr<EHFrameRegistrationPlugin>>
22+
EHFrameRegistrationPlugin::Create(ExecutionSession &ES) {
23+
// Lookup addresseses of the registration/deregistration functions in the
24+
// bootstrap map.
25+
ExecutorAddr RegisterEHFrameSectionWrapper;
26+
ExecutorAddr DeregisterEHFrameSectionWrapper;
27+
if (auto Err = ES.getExecutorProcessControl().getBootstrapSymbols(
28+
{{RegisterEHFrameSectionWrapper,
29+
rt::RegisterEHFrameSectionWrapperName},
30+
{DeregisterEHFrameSectionWrapper,
31+
rt::DeregisterEHFrameSectionWrapperName}}))
32+
return std::move(Err);
33+
34+
return std::make_unique<EHFrameRegistrationPlugin>(
35+
ES, RegisterEHFrameSectionWrapper, DeregisterEHFrameSectionWrapper);
36+
}
2337

2438
void EHFrameRegistrationPlugin::modifyPassConfig(
2539
MaterializationResponsibility &MR, LinkGraph &LG,
2640
PassConfiguration &PassConfig) {
27-
2841
if (LG.getTargetTriple().isOSBinFormatMachO())
2942
PassConfig.PrePrunePasses.insert(
3043
PassConfig.PrePrunePasses.begin(), [](LinkGraph &G) {
@@ -33,92 +46,20 @@ void EHFrameRegistrationPlugin::modifyPassConfig(
3346
return Error::success();
3447
});
3548

36-
PassConfig.PostFixupPasses.push_back(createEHFrameRecorderPass(
37-
LG.getTargetTriple(), [this, &MR](ExecutorAddr Addr, size_t Size) {
38-
if (Addr) {
39-
std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
40-
assert(!InProcessLinks.count(&MR) &&
41-
"Link for MR already being tracked?");
42-
InProcessLinks[&MR] = {Addr, Size};
43-
}
44-
}));
45-
}
46-
47-
Error EHFrameRegistrationPlugin::notifyEmitted(
48-
MaterializationResponsibility &MR) {
49-
50-
ExecutorAddrRange EmittedRange;
51-
{
52-
std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
53-
54-
auto EHFrameRangeItr = InProcessLinks.find(&MR);
55-
if (EHFrameRangeItr == InProcessLinks.end())
56-
return Error::success();
57-
58-
EmittedRange = EHFrameRangeItr->second;
59-
assert(EmittedRange.Start && "eh-frame addr to register can not be null");
60-
InProcessLinks.erase(EHFrameRangeItr);
61-
}
62-
63-
if (auto Err = MR.withResourceKeyDo(
64-
[&](ResourceKey K) { EHFrameRanges[K].push_back(EmittedRange); }))
65-
return Err;
66-
67-
return Registrar->registerEHFrames(EmittedRange);
68-
}
69-
70-
Error EHFrameRegistrationPlugin::notifyFailed(
71-
MaterializationResponsibility &MR) {
72-
std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
73-
InProcessLinks.erase(&MR);
74-
return Error::success();
75-
}
76-
77-
Error EHFrameRegistrationPlugin::notifyRemovingResources(JITDylib &JD,
78-
ResourceKey K) {
79-
std::vector<ExecutorAddrRange> RangesToRemove;
80-
81-
ES.runSessionLocked([&] {
82-
auto I = EHFrameRanges.find(K);
83-
if (I != EHFrameRanges.end()) {
84-
RangesToRemove = std::move(I->second);
85-
EHFrameRanges.erase(I);
49+
PassConfig.PostFixupPasses.push_back([this](LinkGraph &G) -> Error {
50+
if (auto *EHFrame = getEHFrameSection(G)) {
51+
using namespace shared;
52+
auto R = SectionRange(*EHFrame).getRange();
53+
G.allocActions().push_back(
54+
{cantFail(
55+
WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
56+
RegisterEHFrame, R)),
57+
cantFail(
58+
WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
59+
DeregisterEHFrame, R))});
8660
}
61+
return Error::success();
8762
});
88-
89-
Error Err = Error::success();
90-
while (!RangesToRemove.empty()) {
91-
auto RangeToRemove = RangesToRemove.back();
92-
RangesToRemove.pop_back();
93-
assert(RangeToRemove.Start && "Untracked eh-frame range must not be null");
94-
Err = joinErrors(std::move(Err),
95-
Registrar->deregisterEHFrames(RangeToRemove));
96-
}
97-
98-
return Err;
99-
}
100-
101-
void EHFrameRegistrationPlugin::notifyTransferringResources(
102-
JITDylib &JD, ResourceKey DstKey, ResourceKey SrcKey) {
103-
auto SI = EHFrameRanges.find(SrcKey);
104-
if (SI == EHFrameRanges.end())
105-
return;
106-
107-
auto DI = EHFrameRanges.find(DstKey);
108-
if (DI != EHFrameRanges.end()) {
109-
auto &SrcRanges = SI->second;
110-
auto &DstRanges = DI->second;
111-
DstRanges.reserve(DstRanges.size() + SrcRanges.size());
112-
for (auto &SrcRange : SrcRanges)
113-
DstRanges.push_back(std::move(SrcRange));
114-
EHFrameRanges.erase(SI);
115-
} else {
116-
// We need to move SrcKey's ranges over without invalidating the SI
117-
// iterator.
118-
auto Tmp = std::move(SI->second);
119-
EHFrameRanges.erase(SI);
120-
EHFrameRanges[DstKey] = std::move(Tmp);
121-
}
12263
}
12364

12465
} // namespace llvm::orc

0 commit comments

Comments
 (0)