Skip to content

Commit 2d10b7b

Browse files
committed
Reapply "[ORC][llvm-jitlink] Add SimpleLazyReexportsSpeculator..." with fixes.
This reapplies 6d72bf4, which was reverted in 57447d3 to investigate build failures, e.g. https://lab.llvm.org/buildbot/#/builders/3/builds/10114. The original patch contained an invalid unused friend declaration of std::make_shared. This has been removed.
1 parent 57447d3 commit 2d10b7b

File tree

8 files changed

+507
-65
lines changed

8 files changed

+507
-65
lines changed

llvm/include/llvm/ExecutionEngine/Orc/JITLinkReentryTrampolines.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ class JITLinkReentryTrampolines {
6565
Expected<std::unique_ptr<LazyReexportsManager>>
6666
createJITLinkLazyReexportsManager(ObjectLinkingLayer &ObjLinkingLayer,
6767
RedirectableSymbolManager &RSMgr,
68-
JITDylib &PlatformJD);
68+
JITDylib &PlatformJD,
69+
LazyReexportsManager::Listener *L = nullptr);
6970

7071
} // namespace llvm::orc
7172

llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h

Lines changed: 92 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,37 @@ class LazyReexportsManager : public ResourceManager {
179179
lazyReexports(LazyReexportsManager &, SymbolAliasMap);
180180

181181
public:
182+
struct CallThroughInfo {
183+
JITDylibSP JD;
184+
SymbolStringPtr Name;
185+
SymbolStringPtr BodyName;
186+
};
187+
188+
class Listener {
189+
public:
190+
using CallThroughInfo = LazyReexportsManager::CallThroughInfo;
191+
192+
virtual ~Listener();
193+
194+
/// Called under the session lock when new lazy reexports are created.
195+
virtual void onLazyReexportsCreated(JITDylib &JD, ResourceKey K,
196+
const SymbolAliasMap &Reexports) = 0;
197+
198+
/// Called under the session lock when lazy reexports have their ownership
199+
/// transferred to a new ResourceKey.
200+
virtual void onLazyReexportsTransfered(JITDylib &JD, ResourceKey DstK,
201+
ResourceKey SrcK) = 0;
202+
203+
/// Called under the session lock when lazy reexports are removed.
204+
virtual Error onLazyReexportsRemoved(JITDylib &JD, ResourceKey K) = 0;
205+
206+
/// Called outside the session lock when a lazy reexport is called.
207+
/// NOTE: Since this is called outside the session lock there is a chance
208+
/// that the reexport referred to has already been removed. Listeners
209+
/// must be prepared to handle requests for stale reexports.
210+
virtual void onLazyReexportCalled(const CallThroughInfo &CTI) = 0;
211+
};
212+
182213
using OnTrampolinesReadyFn = unique_function<void(
183214
Expected<std::vector<ExecutorSymbolDef>> EntryAddrs)>;
184215
using EmitTrampolinesFn =
@@ -189,7 +220,7 @@ class LazyReexportsManager : public ResourceManager {
189220
/// This will work both in-process and out-of-process.
190221
static Expected<std::unique_ptr<LazyReexportsManager>>
191222
Create(EmitTrampolinesFn EmitTrampolines, RedirectableSymbolManager &RSMgr,
192-
JITDylib &PlatformJD);
223+
JITDylib &PlatformJD, Listener *L = nullptr);
193224

194225
LazyReexportsManager(LazyReexportsManager &&) = delete;
195226
LazyReexportsManager &operator=(LazyReexportsManager &&) = delete;
@@ -199,12 +230,6 @@ class LazyReexportsManager : public ResourceManager {
199230
ResourceKey SrcK) override;
200231

201232
private:
202-
struct CallThroughInfo {
203-
SymbolStringPtr Name;
204-
SymbolStringPtr BodyName;
205-
JITDylibSP JD;
206-
};
207-
208233
class MU;
209234
class Plugin;
210235

@@ -213,7 +238,7 @@ class LazyReexportsManager : public ResourceManager {
213238

214239
LazyReexportsManager(EmitTrampolinesFn EmitTrampolines,
215240
RedirectableSymbolManager &RSMgr, JITDylib &PlatformJD,
216-
Error &Err);
241+
Listener *L, Error &Err);
217242

218243
std::unique_ptr<MaterializationUnit>
219244
createLazyReexports(SymbolAliasMap Reexports);
@@ -229,6 +254,7 @@ class LazyReexportsManager : public ResourceManager {
229254
ExecutionSession &ES;
230255
EmitTrampolinesFn EmitTrampolines;
231256
RedirectableSymbolManager &RSMgr;
257+
Listener *L;
232258

233259
DenseMap<ResourceKey, std::vector<ExecutorAddr>> KeyToReentryAddrs;
234260
DenseMap<ExecutorAddr, CallThroughInfo> CallThroughs;
@@ -242,6 +268,64 @@ lazyReexports(LazyReexportsManager &LRM, SymbolAliasMap Reexports) {
242268
return LRM.createLazyReexports(std::move(Reexports));
243269
}
244270

271+
class SimpleLazyReexportsSpeculator : public LazyReexportsManager::Listener {
272+
public:
273+
using RecordExecutionFunction =
274+
unique_function<void(const CallThroughInfo &CTI)>;
275+
276+
static std::shared_ptr<SimpleLazyReexportsSpeculator>
277+
Create(ExecutionSession &ES, RecordExecutionFunction RecordExec = {}) {
278+
class make_shared_helper : public SimpleLazyReexportsSpeculator {
279+
public:
280+
make_shared_helper(ExecutionSession &ES,
281+
RecordExecutionFunction RecordExec)
282+
: SimpleLazyReexportsSpeculator(ES, std::move(RecordExec)) {}
283+
};
284+
285+
auto Instance =
286+
std::make_shared<make_shared_helper>(ES, std::move(RecordExec));
287+
Instance->WeakThis = Instance;
288+
return Instance;
289+
}
290+
291+
SimpleLazyReexportsSpeculator(SimpleLazyReexportsSpeculator &&) = delete;
292+
SimpleLazyReexportsSpeculator &
293+
operator=(SimpleLazyReexportsSpeculator &&) = delete;
294+
~SimpleLazyReexportsSpeculator() override;
295+
296+
void onLazyReexportsCreated(JITDylib &JD, ResourceKey K,
297+
const SymbolAliasMap &Reexports) override;
298+
299+
void onLazyReexportsTransfered(JITDylib &JD, ResourceKey DstK,
300+
ResourceKey SrcK) override;
301+
302+
Error onLazyReexportsRemoved(JITDylib &JD, ResourceKey K) override;
303+
304+
void onLazyReexportCalled(const CallThroughInfo &CTI) override;
305+
306+
void addSpeculationSuggestions(
307+
std::vector<std::pair<std::string, SymbolStringPtr>> NewSuggestions);
308+
309+
private:
310+
SimpleLazyReexportsSpeculator(ExecutionSession &ES,
311+
RecordExecutionFunction RecordExec)
312+
: ES(ES), RecordExec(std::move(RecordExec)) {}
313+
314+
bool doNextSpeculativeLookup();
315+
316+
class SpeculateTask;
317+
318+
using KeyToFunctionBodiesMap =
319+
DenseMap<ResourceKey, std::vector<SymbolStringPtr>>;
320+
321+
ExecutionSession &ES;
322+
RecordExecutionFunction RecordExec;
323+
std::weak_ptr<SimpleLazyReexportsSpeculator> WeakThis;
324+
DenseMap<JITDylib *, KeyToFunctionBodiesMap> LazyReexports;
325+
std::deque<std::pair<std::string, SymbolStringPtr>> SpeculateSuggestions;
326+
bool SpeculateTaskActive = false;
327+
};
328+
245329
} // End namespace orc
246330
} // End namespace llvm
247331

llvm/include/llvm/ExecutionEngine/Orc/TaskDispatch.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,16 @@ makeGenericNamedTask(FnT &&Fn, const char *Desc = nullptr) {
9292
Desc);
9393
}
9494

95+
/// IdleTask can be used as the basis for low-priority tasks, e.g. speculative
96+
/// lookup.
97+
class IdleTask : public RTTIExtends<IdleTask, Task> {
98+
public:
99+
static char ID;
100+
101+
private:
102+
void anchor() override;
103+
};
104+
95105
/// Abstract base for classes that dispatch ORC Tasks.
96106
class TaskDispatcher {
97107
public:
@@ -118,9 +128,13 @@ class DynamicThreadPoolTaskDispatcher : public TaskDispatcher {
118128
DynamicThreadPoolTaskDispatcher(
119129
std::optional<size_t> MaxMaterializationThreads)
120130
: MaxMaterializationThreads(MaxMaterializationThreads) {}
131+
121132
void dispatch(std::unique_ptr<Task> T) override;
122133
void shutdown() override;
123134
private:
135+
bool canRunMaterializationTaskNow();
136+
bool canRunIdleTaskNow();
137+
124138
std::mutex DispatchMutex;
125139
bool Shutdown = false;
126140
size_t Outstanding = 0;
@@ -129,6 +143,7 @@ class DynamicThreadPoolTaskDispatcher : public TaskDispatcher {
129143
std::optional<size_t> MaxMaterializationThreads;
130144
size_t NumMaterializationThreads = 0;
131145
std::deque<std::unique_ptr<Task>> MaterializationTaskQueue;
146+
std::deque<std::unique_ptr<Task>> IdleTaskQueue;
132147
};
133148

134149
#endif // LLVM_ENABLE_THREADS

llvm/lib/ExecutionEngine/Orc/JITLinkReentryTrampolines.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,8 @@ void JITLinkReentryTrampolines::emit(ResourceTrackerSP RT,
173173
Expected<std::unique_ptr<LazyReexportsManager>>
174174
createJITLinkLazyReexportsManager(ObjectLinkingLayer &ObjLinkingLayer,
175175
RedirectableSymbolManager &RSMgr,
176-
JITDylib &PlatformJD) {
176+
JITDylib &PlatformJD,
177+
LazyReexportsManager::Listener *L) {
177178
auto JLT = JITLinkReentryTrampolines::Create(ObjLinkingLayer);
178179
if (!JLT)
179180
return JLT.takeError();
@@ -184,7 +185,7 @@ createJITLinkLazyReexportsManager(ObjectLinkingLayer &ObjLinkingLayer,
184185
OnTrampolinesReady) mutable {
185186
JLT->emit(std::move(RT), NumTrampolines, std::move(OnTrampolinesReady));
186187
},
187-
RSMgr, PlatformJD);
188+
RSMgr, PlatformJD, L);
188189
}
189190

190191
} // namespace llvm::orc

0 commit comments

Comments
 (0)