LLVM 24.0.0git
JITLinkReentryTrampolines.cpp
Go to the documentation of this file.
1//===----- JITLinkReentryTrampolines.cpp -- JITLink-based trampoline- -----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10
14
15#include <memory>
16
17#define DEBUG_TYPE "orc"
18
19using namespace llvm;
20using namespace llvm::jitlink;
21
22namespace {
23constexpr StringRef ReentryFnName = "__orc_rt_reenter";
24constexpr StringRef ReentrySectionName = "__orc_stubs";
25} // namespace
26
27namespace llvm::orc {
28
31public:
34 jitlink::PassConfiguration &Config) override {
35 Config.PreFixupPasses.push_back(
36 [this](LinkGraph &G) { return recordTrampolineAddrs(G); });
37 }
38
42
46
48 ResourceKey SrcKey) override {}
49
51 std::shared_ptr<std::vector<ExecutorSymbolDef>> Addrs) {
52 std::lock_guard<std::mutex> Lock(M);
53 assert(!PendingAddrs.count(&G) && "Duplicate registration");
54 PendingAddrs[&G] = std::move(Addrs);
55 }
56
58 std::shared_ptr<std::vector<ExecutorSymbolDef>> Addrs;
59 {
60 std::lock_guard<std::mutex> Lock(M);
61 auto I = PendingAddrs.find(&G);
62 if (I == PendingAddrs.end())
63 return Error::success();
64 Addrs = std::move(I->second);
65 PendingAddrs.erase(I);
66 }
67
68 auto *Sec = G.findSectionByName(ReentrySectionName);
69 assert(Sec && "Reentry graph missing reentry section");
70 assert(!Sec->empty() && "Reentry graph is empty");
71
72 for (auto *Sym : Sec->symbols())
73 if (!Sym->hasName())
74 Addrs->push_back({Sym->getAddress(), JITSymbolFlags()});
75
76 return Error::success();
77 }
78
79private:
80 std::mutex M;
82 PendingAddrs;
83};
84
87
88 EmitTrampolineFn EmitTrampoline;
89
90 const auto &TT = ObjLinkingLayer.getExecutionSession().getTargetTriple();
91 switch (TT.getArch()) {
92 case Triple::aarch64:
94 break;
95 case Triple::x86_64:
97 break;
98 default:
99 return make_error<StringError>("JITLinkReentryTrampolines: architecture " +
100 TT.getArchName() + " not supported",
102 }
103
104 return std::make_unique<JITLinkReentryTrampolines>(ObjLinkingLayer,
105 std::move(EmitTrampoline));
106}
107
109 ObjectLinkingLayer &ObjLinkingLayer, EmitTrampolineFn EmitTrampoline)
110 : ObjLinkingLayer(ObjLinkingLayer),
111 EmitTrampoline(std::move(EmitTrampoline)) {
112 auto TAS = std::make_shared<TrampolineAddrScraperPlugin>();
113 TrampolineAddrScraper = TAS.get();
114 ObjLinkingLayer.addPlugin(std::move(TAS));
115}
116
118 size_t NumTrampolines,
119 OnTrampolinesReadyFn OnTrampolinesReady) {
120
121 if (NumTrampolines == 0)
122 return OnTrampolinesReady(std::vector<ExecutorSymbolDef>());
123
124 JITDylibSP JD(&RT->getJITDylib());
125 auto &ES = ObjLinkingLayer.getExecutionSession();
126
127 auto ReentryGraphSym =
128 ES.intern(("__orc_reentry_graph_#" + Twine(++ReentryGraphIdx)).str());
129
130 auto G = std::make_unique<jitlink::LinkGraph>(
131 (*ReentryGraphSym).str(), ES.getSymbolStringPool(), ES.getTargetTriple(),
132 ES.getTargetTriple().getArchPointerBitWidth() / 8, SubtargetFeatures(),
134
135 auto &ReentryFnSym = G->addExternalSymbol(ReentryFnName, 0, false);
136
137 auto &ReentrySection =
138 G->createSection(ReentrySectionName, MemProt::Exec | MemProt::Read);
139
140 for (size_t I = 0; I != NumTrampolines; ++I)
141 EmitTrampoline(*G, ReentrySection, ReentryFnSym).setLive(true);
142
143 auto &FirstBlock = **ReentrySection.blocks().begin();
144 G->addDefinedSymbol(FirstBlock, 0, *ReentryGraphSym, FirstBlock.getSize(),
146
147 auto TrampolineAddrs = std::make_shared<std::vector<ExecutorSymbolDef>>();
148 TrampolineAddrScraper->registerGraph(*G, TrampolineAddrs);
149
150 // Add Graph via object linking layer.
151 if (auto Err = ObjLinkingLayer.add(std::move(RT), std::move(G)))
152 return OnTrampolinesReady(std::move(Err));
153
154 // Trigger graph emission.
155 ES.lookup(
157 SymbolLookupSet(ReentryGraphSym,
160 [OnTrampolinesReady = std::move(OnTrampolinesReady),
161 TrampolineAddrs =
162 std::move(TrampolineAddrs)](Expected<SymbolMap> Result) mutable {
163 if (Result)
164 OnTrampolinesReady(std::move(*TrampolineAddrs));
165 else
166 OnTrampolinesReady(Result.takeError());
167 },
169}
170
174 JITDylib &PlatformJD,
176 auto JLT = JITLinkReentryTrampolines::Create(ObjLinkingLayer);
177 if (!JLT)
178 return JLT.takeError();
179
181 [JLT = std::move(*JLT)](ResourceTrackerSP RT, size_t NumTrampolines,
183 OnTrampolinesReady) mutable {
184 JLT->emit(std::move(RT), NumTrampolines, std::move(OnTrampolinesReady));
185 },
186 RSMgr, PlatformJD, L);
187}
188
189} // namespace llvm::orc
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
Flags for symbols in the JIT.
Definition JITSymbol.h:75
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Manages the enabling and disabling of subtarget specific features.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
Represents a JIT'd dynamic library.
Definition Core.h:676
void registerGraph(LinkGraph &G, std::shared_ptr< std::vector< ExecutorSymbolDef > > Addrs)
void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey, ResourceKey SrcKey) override
void modifyPassConfig(MaterializationResponsibility &MR, jitlink::LinkGraph &G, jitlink::PassConfiguration &Config) override
unique_function< void( Expected< std::vector< ExecutorSymbolDef > > EntryAddrs)> OnTrampolinesReadyFn
LLVM_ABI JITLinkReentryTrampolines(ObjectLinkingLayer &ObjLinkingLayer, EmitTrampolineFn EmitTrampoline)
LLVM_ABI void emit(ResourceTrackerSP RT, size_t NumTrampolines, OnTrampolinesReadyFn OnTrampolinesReady)
static LLVM_ABI Expected< std::unique_ptr< JITLinkReentryTrampolines > > Create(ObjectLinkingLayer &ObjLinkingLayer)
Create trampolines using the default reentry trampoline function for the session triple.
unique_function< jitlink::Symbol &( jitlink::LinkGraph &G, jitlink::Section &Sec, jitlink::Symbol &ReentrySym)> EmitTrampolineFn
unique_function< void( Expected< std::vector< ExecutorSymbolDef > > EntryAddrs)> OnTrampolinesReadyFn
static Expected< std::unique_ptr< LazyReexportsManager > > Create(EmitTrampolinesFn EmitTrampolines, RedirectableSymbolManager &RSMgr, JITDylib &PlatformJD, Listener *L=nullptr)
Create a LazyReexportsManager that uses the ORC runtime for reentry.
Plugin instances can be added to the ObjectLinkingLayer to receive callbacks when code is loaded or e...
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Definition Core.h:350
An ObjectLayer implementation built on JITLink.
Base class for managing redirectable symbols in which a call gets redirected to another symbol in run...
A set of symbols to look up, each associated with a SymbolLookupFlags value.
IntrusiveRefCntPtr< JITDylib > JITDylibSP
Definition Core.h:59
IntrusiveRefCntPtr< ResourceTracker > ResourceTrackerSP
Definition Core.h:58
uintptr_t ResourceKey
Definition Core.h:61
LLVM_ABI Expected< std::unique_ptr< LazyReexportsManager > > createJITLinkLazyReexportsManager(ObjectLinkingLayer &ObjLinkingLayer, RedirectableSymbolManager &RSMgr, JITDylib &PlatformJD, LazyReexportsManager::Listener *L=nullptr)
LLVM_ABI RegisterDependenciesFunction NoDependenciesToRegister
This can be used as the value for a RegisterDependenciesFunction if there are no dependants to regist...
Definition Core.cpp:41
@ Ready
Emitted to memory, but waiting on transitive dependencies.
Definition Core.h:552
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition Error.cpp:94
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1933
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878