Skip to content

Commit 84fe1f6

Browse files
authored
[ORC] Switch to singleton pattern for UnwindInfoManager. (#126691)
The find-dynamic-unwind-info callback registration APIs in libunwind limit the number of callbacks that can be registered. If we use multiple UnwindInfoManager instances, each with their own own callback function (as was the case prior to this patch) we can quickly exceed this limit (see #126611). This patch updates the UnwindInfoManager class to use a singleton pattern, with the single instance shared between all LLVM JITs in the process. This change does _not_ apply to compact unwind info registered through the ORC runtime (which currently installs its own callbacks). As a bonus this change eliminates the need to load an IR "bouncer" module to supply the unique callback for each instance, so support for compact-unwind can be extended to the llvm-jitlink tools (which does not support adding IR).
1 parent 8374d42 commit 84fe1f6

File tree

10 files changed

+146
-290
lines changed

10 files changed

+146
-290
lines changed

llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,6 @@ using SPSRunAsIntFunctionSignature = int32_t(shared::SPSExecutorAddr, int32_t);
9090
} // end namespace rt
9191

9292
namespace rt_alt {
93-
extern const char *UnwindInfoManagerInstanceName;
94-
extern const char *UnwindInfoManagerFindSectionsHelperName;
95-
extern const char *UnwindInfoManagerEnableWrapperName;
96-
extern const char *UnwindInfoManagerDisableWrapperName;
9793
extern const char *UnwindInfoManagerRegisterActionName;
9894
extern const char *UnwindInfoManagerDeregisterActionName;
9995
} // end namespace rt_alt

llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/UnwindInfoManager.h

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,13 @@
1515
#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_UNWINDINFOMANAGER_H
1616

1717
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
18-
#include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorBootstrapService.h"
1918
#include "llvm/Support/Error.h"
2019
#include <map>
2120
#include <mutex>
2221

2322
namespace llvm::orc {
2423

25-
class UnwindInfoManager : public ExecutorBootstrapService {
24+
class UnwindInfoManager {
2625
public:
2726
// This struct's layout should match the unw_dynamic_unwind_sections struct
2827
// from libunwind/src/libunwid_ext.h.
@@ -34,43 +33,40 @@ class UnwindInfoManager : public ExecutorBootstrapService {
3433
size_t compact_unwind_section_length;
3534
};
3635

36+
UnwindInfoManager(UnwindInfoManager &&) = delete;
37+
UnwindInfoManager &operator=(UnwindInfoManager &&) = delete;
38+
~UnwindInfoManager();
39+
3740
/// If the libunwind find-dynamic-unwind-info callback registration APIs are
38-
/// available then this method will return an UnwindInfoManager instance,
39-
/// otherwise it will return nullptr.
40-
static std::unique_ptr<UnwindInfoManager> TryCreate();
41+
/// available then this method will instantiate a global UnwindInfoManager
42+
/// instance suitable for the process and return true. Otherwise it will
43+
/// return false.
44+
static bool TryEnable();
4145

42-
Error shutdown() override;
43-
void addBootstrapSymbols(StringMap<ExecutorAddr> &M) override;
46+
static void addBootstrapSymbols(StringMap<ExecutorAddr> &M);
4447

45-
Error enable(void *FindDynamicUnwindSections);
46-
Error disable(void);
48+
static Error registerSections(ArrayRef<orc::ExecutorAddrRange> CodeRanges,
49+
orc::ExecutorAddr DSOBase,
50+
orc::ExecutorAddrRange DWARFEHFrame,
51+
orc::ExecutorAddrRange CompactUnwind);
4752

48-
Error registerSections(ArrayRef<orc::ExecutorAddrRange> CodeRanges,
49-
orc::ExecutorAddr DSOBase,
50-
orc::ExecutorAddrRange DWARFEHFrame,
51-
orc::ExecutorAddrRange CompactUnwind);
53+
static Error deregisterSections(ArrayRef<orc::ExecutorAddrRange> CodeRanges);
5254

53-
Error deregisterSections(ArrayRef<orc::ExecutorAddrRange> CodeRanges);
55+
private:
56+
UnwindInfoManager() = default;
5457

55-
int findSections(uintptr_t Addr, UnwindSections *Info);
58+
int findSectionsImpl(uintptr_t Addr, UnwindSections *Info);
59+
static int findSections(uintptr_t Addr, UnwindSections *Info);
5660

57-
private:
58-
UnwindInfoManager(int (*AddFindDynamicUnwindSections)(void *),
59-
int (*RemoveFindDynamicUnwindSections)(void *))
60-
: AddFindDynamicUnwindSections(AddFindDynamicUnwindSections),
61-
RemoveFindDynamicUnwindSections(RemoveFindDynamicUnwindSections) {}
61+
Error registerSectionsImpl(ArrayRef<orc::ExecutorAddrRange> CodeRanges,
62+
orc::ExecutorAddr DSOBase,
63+
orc::ExecutorAddrRange DWARFEHFrame,
64+
orc::ExecutorAddrRange CompactUnwind);
6265

63-
static int findSectionsHelper(UnwindInfoManager *Instance, uintptr_t Addr,
64-
UnwindSections *Info);
66+
Error deregisterSectionsImpl(ArrayRef<orc::ExecutorAddrRange> CodeRanges);
6567

6668
std::mutex M;
6769
std::map<uintptr_t, UnwindSections> UWSecs;
68-
69-
int (*AddFindDynamicUnwindSections)(void *) = nullptr;
70-
int (*RemoveFindDynamicUnwindSections)(void *) = nullptr;
71-
void *FindDynamicUnwindSections = nullptr;
72-
73-
static const char *AddFnName, *RemoveFnName;
7470
};
7571

7672
} // namespace llvm::orc

llvm/include/llvm/ExecutionEngine/Orc/UnwindInfoRegistrationPlugin.h

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,17 @@ namespace llvm::orc {
1919

2020
class UnwindInfoRegistrationPlugin : public LinkGraphLinkingLayer::Plugin {
2121
public:
22-
static Expected<std::shared_ptr<UnwindInfoRegistrationPlugin>>
23-
Create(IRLayer &IRL, JITDylib &PlatformJD, ExecutorAddr Instance,
24-
ExecutorAddr FindHelper, ExecutorAddr Enable, ExecutorAddr Disable,
25-
ExecutorAddr Register, ExecutorAddr Deregister);
22+
UnwindInfoRegistrationPlugin(ExecutionSession &ES, ExecutorAddr Register,
23+
ExecutorAddr Deregister)
24+
: ES(ES), Register(Register), Deregister(Deregister) {
25+
DSOBaseName = ES.intern("__jitlink$libunwind_dso_base");
26+
}
2627

2728
static Expected<std::shared_ptr<UnwindInfoRegistrationPlugin>>
28-
Create(IRLayer &IRL, JITDylib &PlatformJD);
29+
Create(ExecutionSession &ES, ExecutorAddr Register, ExecutorAddr Deregister);
2930

30-
~UnwindInfoRegistrationPlugin();
31+
static Expected<std::shared_ptr<UnwindInfoRegistrationPlugin>>
32+
Create(ExecutionSession &ES);
3133

3234
void modifyPassConfig(MaterializationResponsibility &MR,
3335
jitlink::LinkGraph &G,
@@ -49,20 +51,11 @@ class UnwindInfoRegistrationPlugin : public LinkGraphLinkingLayer::Plugin {
4951
ResourceKey SrcKey) override {}
5052

5153
private:
52-
UnwindInfoRegistrationPlugin(ExecutionSession &ES, ExecutorAddr Instance,
53-
ExecutorAddr Disable, ExecutorAddr Register,
54-
ExecutorAddr Deregister)
55-
: ES(ES), Instance(Instance), Disable(Disable), Register(Register),
56-
Deregister(Deregister) {
57-
DSOBaseName = ES.intern("__jitlink$libunwind_dso_base");
58-
}
59-
60-
static Expected<ThreadSafeModule> makeBouncerModule(ExecutionSession &ES);
6154
Error addUnwindInfoRegistrationActions(jitlink::LinkGraph &G);
6255

6356
ExecutionSession &ES;
6457
SymbolStringPtr DSOBaseName;
65-
ExecutorAddr Instance, Disable, Register, Deregister;
58+
ExecutorAddr Register, Deregister;
6659
};
6760

6861
} // namespace llvm::orc

llvm/lib/ExecutionEngine/Orc/ExecutorProcessControl.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,8 @@ SelfExecutorProcessControl::SelfExecutorProcessControl(
5454
// FIXME: Don't add an UnwindInfoManager by default -- it's redundant when
5555
// the ORC runtime is loaded. We'll need a way to document this and
5656
// allow clients to choose.
57-
this->UnwindInfoMgr = UnwindInfoManager::TryCreate();
58-
if (this->UnwindInfoMgr)
59-
this->UnwindInfoMgr->addBootstrapSymbols(this->BootstrapSymbols);
57+
if (UnwindInfoManager::TryEnable())
58+
UnwindInfoManager::addBootstrapSymbols(this->BootstrapSymbols);
6059
#endif // __APPLE__
6160
}
6261

llvm/lib/ExecutionEngine/Orc/LLJIT.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,8 +1241,8 @@ Expected<JITDylibSP> setUpGenericLLVMIRPlatform(LLJIT &J) {
12411241

12421242
// If UseEHFrames hasn't been set then we're good to use compact-unwind.
12431243
if (!UseEHFrames) {
1244-
if (auto UIRP = UnwindInfoRegistrationPlugin::Create(
1245-
J.getIRCompileLayer(), PlatformJD)) {
1244+
if (auto UIRP =
1245+
UnwindInfoRegistrationPlugin::Create(J.getExecutionSession())) {
12461246
OLL->addPlugin(std::move(*UIRP));
12471247
LLVM_DEBUG(dbgs() << "Enabled compact-unwind support.\n");
12481248
} else

llvm/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,6 @@ const char *RunAsIntFunctionWrapperName =
6565

6666
} // end namespace rt
6767
namespace rt_alt {
68-
const char *UnwindInfoManagerInstanceName =
69-
"orc_rt_alt_UnwindInfoManager_Instance";
70-
const char *UnwindInfoManagerFindSectionsHelperName =
71-
"orc_rt_alt_UnwindInfoManager_findSectionsHelper";
72-
const char *UnwindInfoManagerEnableWrapperName =
73-
"orc_rt_alt_UnwindInfoManager_enable";
74-
const char *UnwindInfoManagerDisableWrapperName =
75-
"orc_rt_alt_UnwindInfoManager_disable";
7668
const char *UnwindInfoManagerRegisterActionName =
7769
"orc_rt_alt_UnwindInfoManager_register";
7870
const char *UnwindInfoManagerDeregisterActionName =

0 commit comments

Comments
 (0)