@@ -179,6 +179,37 @@ class LazyReexportsManager : public ResourceManager {
179
179
lazyReexports (LazyReexportsManager &, SymbolAliasMap);
180
180
181
181
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
+
182
213
using OnTrampolinesReadyFn = unique_function<void (
183
214
Expected<std::vector<ExecutorSymbolDef>> EntryAddrs)>;
184
215
using EmitTrampolinesFn =
@@ -189,7 +220,7 @@ class LazyReexportsManager : public ResourceManager {
189
220
// / This will work both in-process and out-of-process.
190
221
static Expected<std::unique_ptr<LazyReexportsManager>>
191
222
Create (EmitTrampolinesFn EmitTrampolines, RedirectableSymbolManager &RSMgr,
192
- JITDylib &PlatformJD);
223
+ JITDylib &PlatformJD, Listener *L = nullptr );
193
224
194
225
LazyReexportsManager (LazyReexportsManager &&) = delete ;
195
226
LazyReexportsManager &operator =(LazyReexportsManager &&) = delete ;
@@ -199,12 +230,6 @@ class LazyReexportsManager : public ResourceManager {
199
230
ResourceKey SrcK) override ;
200
231
201
232
private:
202
- struct CallThroughInfo {
203
- SymbolStringPtr Name;
204
- SymbolStringPtr BodyName;
205
- JITDylibSP JD;
206
- };
207
-
208
233
class MU ;
209
234
class Plugin ;
210
235
@@ -213,7 +238,7 @@ class LazyReexportsManager : public ResourceManager {
213
238
214
239
LazyReexportsManager (EmitTrampolinesFn EmitTrampolines,
215
240
RedirectableSymbolManager &RSMgr, JITDylib &PlatformJD,
216
- Error &Err);
241
+ Listener *L, Error &Err);
217
242
218
243
std::unique_ptr<MaterializationUnit>
219
244
createLazyReexports (SymbolAliasMap Reexports);
@@ -229,6 +254,7 @@ class LazyReexportsManager : public ResourceManager {
229
254
ExecutionSession &ES;
230
255
EmitTrampolinesFn EmitTrampolines;
231
256
RedirectableSymbolManager &RSMgr;
257
+ Listener *L;
232
258
233
259
DenseMap<ResourceKey, std::vector<ExecutorAddr>> KeyToReentryAddrs;
234
260
DenseMap<ExecutorAddr, CallThroughInfo> CallThroughs;
@@ -242,6 +268,64 @@ lazyReexports(LazyReexportsManager &LRM, SymbolAliasMap Reexports) {
242
268
return LRM.createLazyReexports (std::move (Reexports));
243
269
}
244
270
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
+
245
329
} // End namespace orc
246
330
} // End namespace llvm
247
331
0 commit comments