LLVM 24.0.0git
Core.h
Go to the documentation of this file.
1//===------ Core.h -- Core ORC APIs (Layer, JITDylib, etc.) -----*- C++ -*-===//
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//
9// Contains core ORC APIs.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_EXECUTIONENGINE_ORC_CORE_H
14#define LLVM_EXECUTIONENGINE_ORC_CORE_H
15
17#include "llvm/ADT/DenseSet.h"
32#include "llvm/Support/Debug.h"
34
35#include <atomic>
36#include <deque>
37#include <future>
38#include <memory>
39#include <vector>
40
41namespace llvm {
42namespace orc {
43
44// Forward declare some classes.
48class JITDylib;
49class ResourceTracker;
51
52enum class SymbolState : uint8_t;
53
56
59
61
62/// API to remove / transfer ownership of JIT resources.
63class ResourceTracker : public ThreadSafeRefCountedBase<ResourceTracker> {
64private:
65 friend class ExecutionSession;
66 friend class JITDylib;
68
69public:
74
76
77 /// Return the JITDylib targeted by this tracker.
79 return *reinterpret_cast<JITDylib *>(JDAndFlag.load() &
80 ~static_cast<uintptr_t>(1));
81 }
82
83 /// Runs the given callback under the session lock, passing in the associated
84 /// ResourceKey. This is the safe way to associate resources with trackers.
85 template <typename Func> Error withResourceKeyDo(Func &&F);
86
87 /// Remove all resources associated with this key.
89
90 /// Transfer all resources associated with this key to the given
91 /// tracker, which must target the same JITDylib as this one.
93
94 /// Return true if this tracker has become defunct.
95 bool isDefunct() const { return JDAndFlag.load() & 0x1; }
96
97 /// Returns the key associated with this tracker.
98 /// This method should not be used except for debug logging: there is no
99 /// guarantee that the returned value will remain valid.
100 ResourceKey getKeyUnsafe() const { return reinterpret_cast<uintptr_t>(this); }
101
102private:
104
105 void makeDefunct();
106
107 std::atomic_uintptr_t JDAndFlag;
108};
109
110/// Listens for ResourceTracker operations.
112public:
114
115 /// This function will be called *outside* the session lock. ResourceManagers
116 /// should perform book-keeping under the session lock, and any expensive
117 /// cleanup outside the session lock.
119
120 /// This function will be called *inside* the session lock. ResourceManagers
121 /// DO NOT need to re-lock the session.
123 ResourceKey SrcK) = 0;
124};
125
126/// Lookup flags that apply to each dylib in the search order for a lookup.
127///
128/// If MatchHiddenSymbolsOnly is used (the default) for a given dylib, then
129/// only symbols in that Dylib's interface will be searched. If
130/// MatchHiddenSymbols is used then symbols with hidden visibility will match
131/// as well.
133
134/// Describes the kind of lookup being performed. The lookup kind is passed to
135/// symbol generators (if they're invoked) to help them determine what
136/// definitions to generate.
137///
138/// Static -- Lookup is being performed as-if at static link time (e.g.
139/// generators representing static archives should pull in new
140/// definitions).
141///
142/// DLSym -- Lookup is being performed as-if at runtime (e.g. generators
143/// representing static archives should not pull in new definitions).
144enum class LookupKind { Static, DLSym };
145
146/// A list of (JITDylib*, JITDylibLookupFlags) pairs to be used as a search
147/// order during symbol lookup.
149 std::vector<std::pair<JITDylib *, JITDylibLookupFlags>>;
150
151/// Convenience function for creating a search order from an ArrayRef of
152/// JITDylib*, all with the same flags.
157 O.reserve(JDs.size());
158 for (auto *JD : JDs)
159 O.push_back(std::make_pair(JD, Flags));
160 return O;
161}
162
171
172/// A map of Symbols to (Symbol, Flags) pairs.
174
175/// Callback to notify client that symbols have been resolved.
177
178/// Callback to register the dependencies for a given query.
180 std::function<void(const SymbolDependenceMap &)>;
181
182/// This can be used as the value for a RegisterDependenciesFunction if there
183/// are no dependants to register with.
185
187 : public ErrorInfo<ResourceTrackerDefunct> {
188public:
189 static char ID;
190
192 std::error_code convertToErrorCode() const override;
193 void log(raw_ostream &OS) const override;
194
195private:
197};
198
199/// Returned by operations that fail because a JITDylib has been closed.
200class LLVM_ABI JITDylibDefunct : public ErrorInfo<JITDylibDefunct> {
201public:
202 static char ID;
203
205 std::error_code convertToErrorCode() const override;
206 void log(raw_ostream &OS) const override;
207
208private:
209 JITDylibSP JD;
210};
211
212/// Used to notify a JITDylib that the given set of symbols failed to
213/// materialize.
214class LLVM_ABI FailedToMaterialize : public ErrorInfo<FailedToMaterialize> {
215public:
216 static char ID;
217
218 FailedToMaterialize(std::shared_ptr<SymbolStringPool> SSP,
219 std::shared_ptr<SymbolDependenceMap> Symbols);
220 ~FailedToMaterialize() override;
221 std::error_code convertToErrorCode() const override;
222 void log(raw_ostream &OS) const override;
223 const SymbolDependenceMap &getSymbols() const { return *Symbols; }
224
225private:
226 std::shared_ptr<SymbolStringPool> SSP;
227 std::shared_ptr<SymbolDependenceMap> Symbols;
228};
229
230/// Used to report failure due to unsatisfiable symbol dependencies.
232 : public ErrorInfo<UnsatisfiedSymbolDependencies> {
233public:
234 static char ID;
235
236 UnsatisfiedSymbolDependencies(std::shared_ptr<SymbolStringPool> SSP,
237 JITDylibSP JD, SymbolNameSet FailedSymbols,
238 SymbolDependenceMap BadDeps,
239 std::string Explanation);
240 std::error_code convertToErrorCode() const override;
241 void log(raw_ostream &OS) const override;
242
243private:
244 std::shared_ptr<SymbolStringPool> SSP;
245 JITDylibSP JD;
246 SymbolNameSet FailedSymbols;
247 SymbolDependenceMap BadDeps;
248 std::string Explanation;
249};
250
251/// Used to notify clients when symbols can not be found during a lookup.
252class LLVM_ABI SymbolsNotFound : public ErrorInfo<SymbolsNotFound> {
253public:
254 static char ID;
255
256 SymbolsNotFound(std::shared_ptr<SymbolStringPool> SSP, SymbolNameSet Symbols);
257 SymbolsNotFound(std::shared_ptr<SymbolStringPool> SSP,
258 SymbolNameVector Symbols);
259 std::error_code convertToErrorCode() const override;
260 void log(raw_ostream &OS) const override;
261 std::shared_ptr<SymbolStringPool> getSymbolStringPool() { return SSP; }
262 const SymbolNameVector &getSymbols() const { return Symbols; }
263
264private:
265 std::shared_ptr<SymbolStringPool> SSP;
266 SymbolNameVector Symbols;
267};
268
269/// Used to notify clients that a set of symbols could not be removed.
271 : public ErrorInfo<SymbolsCouldNotBeRemoved> {
272public:
273 static char ID;
274
275 SymbolsCouldNotBeRemoved(std::shared_ptr<SymbolStringPool> SSP,
276 SymbolNameSet Symbols);
277 std::error_code convertToErrorCode() const override;
278 void log(raw_ostream &OS) const override;
279 std::shared_ptr<SymbolStringPool> getSymbolStringPool() { return SSP; }
280 const SymbolNameSet &getSymbols() const { return Symbols; }
281
282private:
283 std::shared_ptr<SymbolStringPool> SSP;
284 SymbolNameSet Symbols;
285};
286
287/// Errors of this type should be returned if a module fails to include
288/// definitions that are claimed by the module's associated
289/// MaterializationResponsibility. If this error is returned it is indicative of
290/// a broken transformation / compiler / object cache.
292 : public ErrorInfo<MissingSymbolDefinitions> {
293public:
294 static char ID;
295
296 MissingSymbolDefinitions(std::shared_ptr<SymbolStringPool> SSP,
297 std::string ModuleName, SymbolNameVector Symbols)
298 : SSP(std::move(SSP)), ModuleName(std::move(ModuleName)),
299 Symbols(std::move(Symbols)) {}
300 std::error_code convertToErrorCode() const override;
301 void log(raw_ostream &OS) const override;
302 std::shared_ptr<SymbolStringPool> getSymbolStringPool() { return SSP; }
303 const std::string &getModuleName() const { return ModuleName; }
304 const SymbolNameVector &getSymbols() const { return Symbols; }
305private:
306 std::shared_ptr<SymbolStringPool> SSP;
307 std::string ModuleName;
308 SymbolNameVector Symbols;
309};
310
311/// Errors of this type should be returned if a module contains definitions for
312/// symbols that are not claimed by the module's associated
313/// MaterializationResponsibility. If this error is returned it is indicative of
314/// a broken transformation / compiler / object cache.
316 : public ErrorInfo<UnexpectedSymbolDefinitions> {
317public:
318 static char ID;
319
320 UnexpectedSymbolDefinitions(std::shared_ptr<SymbolStringPool> SSP,
321 std::string ModuleName, SymbolNameVector Symbols)
322 : SSP(std::move(SSP)), ModuleName(std::move(ModuleName)),
323 Symbols(std::move(Symbols)) {}
324 std::error_code convertToErrorCode() const override;
325 void log(raw_ostream &OS) const override;
326 std::shared_ptr<SymbolStringPool> getSymbolStringPool() { return SSP; }
327 const std::string &getModuleName() const { return ModuleName; }
328 const SymbolNameVector &getSymbols() const { return Symbols; }
329private:
330 std::shared_ptr<SymbolStringPool> SSP;
331 std::string ModuleName;
332 SymbolNameVector Symbols;
333};
334
335/// A set of symbols and the their dependencies. Used to describe dependencies
336/// for the MaterializationResponsibility::notifyEmitted operation.
341
342/// Tracks responsibility for materialization, and mediates interactions between
343/// MaterializationUnits and JDs.
344///
345/// An instance of this class is passed to MaterializationUnits when their
346/// materialize method is called. It allows MaterializationUnits to resolve and
347/// emit symbols, or abandon materialization by notifying any unmaterialized
348/// symbols of an error.
350 friend class ExecutionSession;
351 friend class JITDylib;
352
353public:
357
358 /// Destruct a MaterializationResponsibility instance. In debug mode
359 /// this asserts that all symbols being tracked have been either
360 /// emitted or notified of an error.
362
363 /// Return the ResourceTracker associated with this instance.
364 const ResourceTrackerSP &getResourceTracker() const { return RT; }
365
366 /// Runs the given callback under the session lock, passing in the associated
367 /// ResourceKey. This is the safe way to associate resources with trackers.
368 template <typename Func> Error withResourceKeyDo(Func &&F) const {
369 return RT->withResourceKeyDo(std::forward<Func>(F));
370 }
371
372 /// Returns the target JITDylib that these symbols are being materialized
373 /// into.
374 JITDylib &getTargetJITDylib() const { return JD; }
375
376 /// Returns the ExecutionSession for this instance.
378
379 /// Returns the symbol flags map for this responsibility instance.
380 /// Note: The returned flags may have transient flags (Lazy, Materializing)
381 /// set. These should be stripped with JITSymbolFlags::stripTransientFlags
382 /// before using.
383 const SymbolFlagsMap &getSymbols() const { return SymbolFlags; }
384
385 /// Returns the initialization pseudo-symbol, if any. This symbol will also
386 /// be present in the SymbolFlagsMap for this MaterializationResponsibility
387 /// object.
388 const SymbolStringPtr &getInitializerSymbol() const { return InitSymbol; }
389
390 /// Returns the names of any symbols covered by this
391 /// MaterializationResponsibility object that have queries pending. This
392 /// information can be used to return responsibility for unrequested symbols
393 /// back to the JITDylib via the delegate method.
395
396 /// Notifies the target JITDylib that the given symbols have been resolved.
397 /// This will update the given symbols' addresses in the JITDylib, and notify
398 /// any pending queries on the given symbols of their resolution. The given
399 /// symbols must be ones covered by this MaterializationResponsibility
400 /// instance. Individual calls to this method may resolve a subset of the
401 /// symbols, but all symbols must have been resolved prior to calling emit.
402 ///
403 /// This method will return an error if any symbols being resolved have been
404 /// moved to the error state due to the failure of a dependency. If this
405 /// method returns an error then clients should log it and call
406 /// failMaterialize. If no dependencies have been registered for the
407 /// symbols covered by this MaterializationResponsibility then this method
408 /// is guaranteed to return Error::success() and can be wrapped with cantFail.
409 Error notifyResolved(const SymbolMap &Symbols);
410
411 /// Notifies the target JITDylib (and any pending queries on that JITDylib)
412 /// that all symbols covered by this MaterializationResponsibility instance
413 /// have been emitted.
414 ///
415 /// The DepGroups array describes the dependencies of symbols being emitted on
416 /// symbols that are outside this MaterializationResponsibility object. Each
417 /// group consists of a pair of a set of symbols and a SymbolDependenceMap
418 /// that describes the dependencies for the symbols in the first set. The
419 /// elements of DepGroups must be non-overlapping (no symbol should appear in
420 /// more than one of hte symbol sets), but do not have to be exhaustive. Any
421 /// symbol in this MaterializationResponsibility object that is not covered
422 /// by an entry will be treated as having no dependencies.
423 ///
424 /// This method will return an error if any symbols being resolved have been
425 /// moved to the error state due to the failure of a dependency. If this
426 /// method returns an error then clients should log it and call
427 /// failMaterialize. If no dependencies have been registered for the
428 /// symbols covered by this MaterializationResponsibility then this method
429 /// is guaranteed to return Error::success() and can be wrapped with cantFail.
431
432 /// Attempt to claim responsibility for new definitions. This method can be
433 /// used to claim responsibility for symbols that are added to a
434 /// materialization unit during the compilation process (e.g. literal pool
435 /// symbols). Symbol linkage rules are the same as for symbols that are
436 /// defined up front: duplicate strong definitions will result in errors.
437 /// Duplicate weak definitions will be discarded (in which case they will
438 /// not be added to this responsibility instance).
439 ///
440 /// This method can be used by materialization units that want to add
441 /// additional symbols at materialization time (e.g. stubs, compile
442 /// callbacks, metadata).
444
445 /// Notify all not-yet-emitted covered by this MaterializationResponsibility
446 /// instance that an error has occurred.
447 /// This will remove all symbols covered by this MaterializationResponsibility
448 /// from the target JITDylib, and send an error to any queries waiting on
449 /// these symbols.
450 void failMaterialization();
451
452 /// Transfers responsibility to the given MaterializationUnit for all
453 /// symbols defined by that MaterializationUnit. This allows
454 /// materializers to break up work based on run-time information (e.g.
455 /// by introspecting which symbols have actually been looked up and
456 /// materializing only those).
457 Error replace(std::unique_ptr<MaterializationUnit> MU);
458
459 /// Delegates responsibility for the given symbols to the returned
460 /// materialization responsibility. Useful for breaking up work between
461 /// threads, or different kinds of materialization processes.
463 delegate(const SymbolNameSet &Symbols);
464
465private:
466 /// Create a MaterializationResponsibility for the given JITDylib and
467 /// initial symbols.
469 SymbolFlagsMap SymbolFlags,
470 SymbolStringPtr InitSymbol)
471 : JD(RT->getJITDylib()), RT(std::move(RT)),
472 SymbolFlags(std::move(SymbolFlags)), InitSymbol(std::move(InitSymbol)) {
473 assert(!this->SymbolFlags.empty() && "Materializing nothing?");
474 }
475
476 JITDylib &JD;
478 SymbolFlagsMap SymbolFlags;
479 SymbolStringPtr InitSymbol;
480};
481
482/// A materialization unit for symbol aliases. Allows existing symbols to be
483/// aliased with alternate flags.
485public:
486 /// SourceJD is allowed to be nullptr, in which case the source JITDylib is
487 /// taken to be whatever JITDylib these definitions are materialized in (and
488 /// MatchNonExported has no effect). This is useful for defining aliases
489 /// within a JITDylib.
490 ///
491 /// Note: Care must be taken that no sets of aliases form a cycle, as such
492 /// a cycle will result in a deadlock when any symbol in the cycle is
493 /// resolved.
495 JITDylibLookupFlags SourceJDLookupFlags,
496 SymbolAliasMap Aliases);
497
498 StringRef getName() const override;
499
500private:
501 void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
502 void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
504 extractFlags(const SymbolAliasMap &Aliases);
505
506 JITDylib *SourceJD = nullptr;
507 JITDylibLookupFlags SourceJDLookupFlags;
508 SymbolAliasMap Aliases;
509};
510
511/// Create a ReExportsMaterializationUnit with the given aliases.
512/// Useful for defining symbol aliases.: E.g., given a JITDylib JD containing
513/// symbols "foo" and "bar", we can define aliases "baz" (for "foo") and "qux"
514/// (for "bar") with: \code{.cpp}
515/// SymbolStringPtr Baz = ...;
516/// SymbolStringPtr Qux = ...;
517/// if (auto Err = JD.define(symbolAliases({
518/// {Baz, { Foo, JITSymbolFlags::Exported }},
519/// {Qux, { Bar, JITSymbolFlags::Weak }}}))
520/// return Err;
521/// \endcode
522inline std::unique_ptr<ReExportsMaterializationUnit>
524 return std::make_unique<ReExportsMaterializationUnit>(
525 nullptr, JITDylibLookupFlags::MatchAllSymbols, std::move(Aliases));
526}
527
528/// Create a materialization unit for re-exporting symbols from another JITDylib
529/// with alternative names/flags.
530/// SourceJD will be searched using the given JITDylibLookupFlags.
531inline std::unique_ptr<ReExportsMaterializationUnit>
533 JITDylibLookupFlags SourceJDLookupFlags =
535 return std::make_unique<ReExportsMaterializationUnit>(
536 &SourceJD, SourceJDLookupFlags, std::move(Aliases));
537}
538
539/// Build a SymbolAliasMap for the common case where you want to re-export
540/// symbols from another JITDylib with the same linkage/flags.
542buildSimpleReexportsAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols);
543
544/// Represents the state that a symbol has reached during materialization.
545enum class SymbolState : uint8_t {
546 Invalid, /// No symbol should be in this state.
547 NeverSearched, /// Added to the symbol table, never queried.
548 Materializing, /// Queried, materialization begun.
549 Resolved, /// Assigned address, still materializing.
550 Emitted, /// Emitted to memory, but waiting on transitive dependencies.
551 Ready = 0x3f /// Ready and safe for clients to access.
552};
553
554/// A symbol query that returns results via a callback when results are
555/// ready.
556///
557/// makes a callback when all symbols are available.
559 friend class ExecutionSession;
561 friend class JITDylib;
564
565public:
566 /// Create a query for the given symbols. The NotifyComplete
567 /// callback will be called once all queried symbols reach the given
568 /// minimum state.
570 SymbolState RequiredState,
571 SymbolsResolvedCallback NotifyComplete);
572
573 /// Notify the query that a requested symbol has reached the required state.
576
577 /// Returns true if all symbols covered by this query have been
578 /// resolved.
579 bool isComplete() const { return OutstandingSymbolsCount == 0; }
580
581
582private:
583 void handleComplete(ExecutionSession &ES);
584
585 SymbolState getRequiredState() { return RequiredState; }
586
587 void addQueryDependence(JITDylib &JD, SymbolStringPtr Name);
588
589 void removeQueryDependence(JITDylib &JD, const SymbolStringPtr &Name);
590
591 void dropSymbol(const SymbolStringPtr &Name);
592
593 void handleFailed(Error Err);
594
595 void detach();
596
597 SymbolsResolvedCallback NotifyComplete;
598 SymbolDependenceMap QueryRegistrations;
599 SymbolMap ResolvedSymbols;
600 size_t OutstandingSymbolsCount;
601 SymbolState RequiredState;
602};
603
604/// Wraps state for a lookup-in-progress.
605/// DefinitionGenerators can optionally take ownership of a LookupState object
606/// to suspend a lookup-in-progress while they search for definitions.
608 friend class OrcV2CAPIHelper;
609 friend class ExecutionSession;
610
611public:
616
617 /// Continue the lookup. This can be called by DefinitionGenerators
618 /// to re-start a captured query-application operation.
619 LLVM_ABI void continueLookup(Error Err);
620
621private:
622 LookupState(std::unique_ptr<InProgressLookupState> IPLS);
623
624 // For C API.
625 void reset(InProgressLookupState *IPLS);
626
627 std::unique_ptr<InProgressLookupState> IPLS;
628};
629
630/// Definition generators can be attached to JITDylibs to generate new
631/// definitions for otherwise unresolved symbols during lookup.
633 friend class ExecutionSession;
634
635public:
636 virtual ~DefinitionGenerator();
637
638 /// DefinitionGenerators should override this method to insert new
639 /// definitions into the parent JITDylib. K specifies the kind of this
640 /// lookup. JD specifies the target JITDylib being searched, and
641 /// JDLookupFlags specifies whether the search should match against
642 /// hidden symbols. Finally, Symbols describes the set of unresolved
643 /// symbols and their associated lookup flags.
645 JITDylibLookupFlags JDLookupFlags,
646 const SymbolLookupSet &LookupSet) = 0;
647
648private:
649 std::mutex M;
650 bool InUse = false;
651 std::deque<LookupState> PendingLookups;
652};
653
654/// Represents a JIT'd dynamic library.
655///
656/// This class aims to mimic the behavior of a regular dylib or shared object,
657/// but without requiring the contained program representations to be compiled
658/// up-front. The JITDylib's content is defined by adding MaterializationUnits,
659/// and contained MaterializationUnits will typically rely on the JITDylib's
660/// links-against order to resolve external references (similar to a regular
661/// dylib).
662///
663/// The JITDylib object is a thin wrapper that references state held by the
664/// ExecutionSession. JITDylibs can be removed, clearing this underlying state
665/// and leaving the JITDylib object in a defunct state. In this state the
666/// JITDylib's name is guaranteed to remain accessible. If the ExecutionSession
667/// is still alive then other operations are callable but will return an Error
668/// or null result (depending on the API). It is illegal to call any operation
669/// other than getName on a JITDylib after the ExecutionSession has been torn
670/// down.
671///
672/// JITDylibs cannot be moved or copied. Their address is stable, and useful as
673/// a key in some JIT data structures.
674class JITDylib : public ThreadSafeRefCountedBase<JITDylib>,
675 public jitlink::JITLinkDylib {
677 friend class ExecutionSession;
678 friend class Platform;
680public:
681
682 JITDylib(const JITDylib &) = delete;
683 JITDylib &operator=(const JITDylib &) = delete;
684 JITDylib(JITDylib &&) = delete;
687
688 /// Get a reference to the ExecutionSession for this JITDylib.
689 ///
690 /// It is legal to call this method on a defunct JITDylib, however the result
691 /// will only usable if the ExecutionSession is still alive. If this JITDylib
692 /// is held by an error that may have torn down the JIT then the result
693 /// should not be used.
694 ExecutionSession &getExecutionSession() const { return ES; }
695
696 /// Dump current JITDylib state to OS.
697 ///
698 /// It is legal to call this method on a defunct JITDylib.
699 LLVM_ABI void dump(raw_ostream &OS);
700
701 /// Calls remove on all trackers currently associated with this JITDylib.
702 /// Does not run static deinits.
703 ///
704 /// Note that removal happens outside the session lock, so new code may be
705 /// added concurrently while the clear is underway, and the newly added
706 /// code will *not* be cleared. Adding new code concurrently with a clear
707 /// is usually a bug and should be avoided.
708 ///
709 /// It is illegal to call this method on a defunct JITDylib and the client
710 /// is responsible for ensuring that they do not do so.
712
713 /// Get the default resource tracker for this JITDylib.
714 ///
715 /// It is illegal to call this method on a defunct JITDylib and the client
716 /// is responsible for ensuring that they do not do so.
718
719 /// Create a resource tracker for this JITDylib.
720 ///
721 /// It is illegal to call this method on a defunct JITDylib and the client
722 /// is responsible for ensuring that they do not do so.
724
725 /// Adds a definition generator to this JITDylib and returns a referenece to
726 /// it.
727 ///
728 /// When JITDylibs are searched during lookup, if no existing definition of
729 /// a symbol is found, then any generators that have been added are run (in
730 /// the order that they were added) to potentially generate a definition.
731 ///
732 /// It is illegal to call this method on a defunct JITDylib and the client
733 /// is responsible for ensuring that they do not do so.
734 template <typename GeneratorT>
735 GeneratorT &addGenerator(std::unique_ptr<GeneratorT> DefGenerator);
736
737 /// Remove a definition generator from this JITDylib.
738 ///
739 /// The given generator must exist in this JITDylib's generators list (i.e.
740 /// have been added and not yet removed).
741 ///
742 /// It is illegal to call this method on a defunct JITDylib and the client
743 /// is responsible for ensuring that they do not do so.
745
746 /// Set the link order to be used when fixing up definitions in JITDylib.
747 /// This will replace the previous link order, and apply to any symbol
748 /// resolutions made for definitions in this JITDylib after the call to
749 /// setLinkOrder (even if the definition itself was added before the
750 /// call).
751 ///
752 /// If LinkAgainstThisJITDylibFirst is true (the default) then this JITDylib
753 /// will add itself to the beginning of the LinkOrder (Clients should not
754 /// put this JITDylib in the list in this case, to avoid redundant lookups).
755 ///
756 /// If LinkAgainstThisJITDylibFirst is false then the link order will be used
757 /// as-is. The primary motivation for this feature is to support deliberate
758 /// shadowing of symbols in this JITDylib by a facade JITDylib. For example,
759 /// the facade may resolve function names to stubs, and the stubs may compile
760 /// lazily by looking up symbols in this dylib. Adding the facade dylib
761 /// as the first in the link order (instead of this dylib) ensures that
762 /// definitions within this dylib resolve to the lazy-compiling stubs,
763 /// rather than immediately materializing the definitions in this dylib.
764 ///
765 /// It is illegal to call this method on a defunct JITDylib and the client
766 /// is responsible for ensuring that they do not do so.
767 LLVM_ABI void setLinkOrder(JITDylibSearchOrder NewSearchOrder,
768 bool LinkAgainstThisJITDylibFirst = true);
769
770 /// Append the given JITDylibSearchOrder to the link order for this
771 /// JITDylib (discarding any elements already present in this JITDylib's
772 /// link order).
773 LLVM_ABI void addToLinkOrder(const JITDylibSearchOrder &NewLinks);
774
775 /// Add the given JITDylib to the link order for definitions in this
776 /// JITDylib.
777 ///
778 /// It is illegal to call this method on a defunct JITDylib and the client
779 /// is responsible for ensuring that they do not do so.
780 LLVM_ABI void
782 JITDylibLookupFlags JDLookupFlags =
784
785 /// Replace OldJD with NewJD in the link order if OldJD is present.
786 /// Otherwise this operation is a no-op.
787 ///
788 /// It is illegal to call this method on a defunct JITDylib and the client
789 /// is responsible for ensuring that they do not do so.
790 LLVM_ABI void
791 replaceInLinkOrder(JITDylib &OldJD, JITDylib &NewJD,
792 JITDylibLookupFlags JDLookupFlags =
794
795 /// Remove the given JITDylib from the link order for this JITDylib if it is
796 /// present. Otherwise this operation is a no-op.
797 ///
798 /// It is illegal to call this method on a defunct JITDylib and the client
799 /// is responsible for ensuring that they do not do so.
801
802 /// Do something with the link order (run under the session lock).
803 ///
804 /// It is illegal to call this method on a defunct JITDylib and the client
805 /// is responsible for ensuring that they do not do so.
806 template <typename Func>
807 auto withLinkOrderDo(Func &&F)
808 -> decltype(F(std::declval<const JITDylibSearchOrder &>()));
809
810 /// Define all symbols provided by the materialization unit to be part of this
811 /// JITDylib.
812 ///
813 /// If RT is not specified then the default resource tracker will be used.
814 ///
815 /// This overload always takes ownership of the MaterializationUnit. If any
816 /// errors occur, the MaterializationUnit consumed.
817 ///
818 /// It is illegal to call this method on a defunct JITDylib and the client
819 /// is responsible for ensuring that they do not do so.
820 template <typename MaterializationUnitType>
821 Error define(std::unique_ptr<MaterializationUnitType> &&MU,
822 ResourceTrackerSP RT = nullptr);
823
824 /// Define all symbols provided by the materialization unit to be part of this
825 /// JITDylib.
826 ///
827 /// This overload only takes ownership of the MaterializationUnit no error is
828 /// generated. If an error occurs, ownership remains with the caller. This
829 /// may allow the caller to modify the MaterializationUnit to correct the
830 /// issue, then re-call define.
831 ///
832 /// It is illegal to call this method on a defunct JITDylib and the client
833 /// is responsible for ensuring that they do not do so.
834 template <typename MaterializationUnitType>
835 Error define(std::unique_ptr<MaterializationUnitType> &MU,
836 ResourceTrackerSP RT = nullptr);
837
838 /// Tries to remove the given symbols.
839 ///
840 /// If any symbols are not defined in this JITDylib this method will return
841 /// a SymbolsNotFound error covering the missing symbols.
842 ///
843 /// If all symbols are found but some symbols are in the process of being
844 /// materialized this method will return a SymbolsCouldNotBeRemoved error.
845 ///
846 /// On success, all symbols are removed. On failure, the JITDylib state is
847 /// left unmodified (no symbols are removed).
848 ///
849 /// It is illegal to call this method on a defunct JITDylib and the client
850 /// is responsible for ensuring that they do not do so.
851 LLVM_ABI Error remove(const SymbolNameSet &Names);
852
853 /// Returns the given JITDylibs and all of their transitive dependencies in
854 /// DFS order (based on linkage relationships). Each JITDylib will appear
855 /// only once.
856 ///
857 /// If any JITDylib in the order is defunct then this method will return an
858 /// error, otherwise returns the order.
861
862 /// Returns the given JITDylibs and all of their transitive dependencies in
863 /// reverse DFS order (based on linkage relationships). Each JITDylib will
864 /// appear only once.
865 ///
866 /// If any JITDylib in the order is defunct then this method will return an
867 /// error, otherwise returns the order.
870
871 /// Return this JITDylib and its transitive dependencies in DFS order
872 /// based on linkage relationships.
873 ///
874 /// If any JITDylib in the order is defunct then this method will return an
875 /// error, otherwise returns the order.
877
878 /// Rteurn this JITDylib and its transitive dependencies in reverse DFS order
879 /// based on linkage relationships.
880 ///
881 /// If any JITDylib in the order is defunct then this method will return an
882 /// error, otherwise returns the order.
884
885private:
886 using AsynchronousSymbolQuerySet =
887 std::set<std::shared_ptr<AsynchronousSymbolQuery>>;
888
889 using AsynchronousSymbolQueryList =
890 std::vector<std::shared_ptr<AsynchronousSymbolQuery>>;
891
892 struct UnmaterializedInfo {
893 UnmaterializedInfo(std::unique_ptr<MaterializationUnit> MU,
894 ResourceTracker *RT)
895 : MU(std::move(MU)), RT(RT) {}
896
897 std::unique_ptr<MaterializationUnit> MU;
898 ResourceTracker *RT;
899 };
900
901 using UnmaterializedInfosMap =
902 DenseMap<SymbolStringPtr, std::shared_ptr<UnmaterializedInfo>>;
903
904 using UnmaterializedInfosList =
905 std::vector<std::shared_ptr<UnmaterializedInfo>>;
906
907 // Information about not-yet-ready symbol.
908 // * DefiningEDU will point to the EmissionDepUnit that defines the symbol.
909 // * DependantEDUs will hold pointers to any EmissionDepUnits currently
910 // waiting on this symbol.
911 // * Pending queries holds any not-yet-completed queries that include this
912 // symbol.
913 struct MaterializingInfo {
914 friend class ExecutionSession;
915
916 LLVM_ABI void addQuery(std::shared_ptr<AsynchronousSymbolQuery> Q);
917 LLVM_ABI void removeQuery(const AsynchronousSymbolQuery &Q);
918 LLVM_ABI AsynchronousSymbolQueryList
919 takeQueriesMeeting(SymbolState RequiredState);
920 AsynchronousSymbolQueryList takeAllPendingQueries() {
921 return std::move(PendingQueries);
922 }
923 bool hasQueriesPending() const { return !PendingQueries.empty(); }
924 const AsynchronousSymbolQueryList &pendingQueries() const {
925 return PendingQueries;
926 }
927 private:
928 AsynchronousSymbolQueryList PendingQueries;
929 };
930
931 using MaterializingInfosMap = DenseMap<SymbolStringPtr, MaterializingInfo>;
932
933 class SymbolTableEntry {
934 public:
935 SymbolTableEntry() = default;
936 SymbolTableEntry(JITSymbolFlags Flags)
937 : Flags(Flags), State(static_cast<uint8_t>(SymbolState::NeverSearched)),
938 MaterializerAttached(false) {}
939
940 ExecutorAddr getAddress() const { return Addr; }
941 JITSymbolFlags getFlags() const { return Flags; }
942 SymbolState getState() const { return static_cast<SymbolState>(State); }
943
944 bool hasMaterializerAttached() const { return MaterializerAttached; }
945
946 void setAddress(ExecutorAddr Addr) { this->Addr = Addr; }
947 void setFlags(JITSymbolFlags Flags) { this->Flags = Flags; }
948 void setState(SymbolState State) {
949 assert(static_cast<uint8_t>(State) < (1 << 6) &&
950 "State does not fit in bitfield");
951 this->State = static_cast<uint8_t>(State);
952 }
953
954 void setMaterializerAttached(bool MaterializerAttached) {
955 this->MaterializerAttached = MaterializerAttached;
956 }
957
958 ExecutorSymbolDef getSymbol() const { return {Addr, Flags}; }
959
960 private:
961 ExecutorAddr Addr;
962 JITSymbolFlags Flags;
963 uint8_t State : 7;
964 uint8_t MaterializerAttached : 1;
965 };
966
967 using SymbolTable = DenseMap<SymbolStringPtr, SymbolTableEntry>;
968
969 JITDylib(ExecutionSession &ES, std::string Name);
970
971 struct RemoveTrackerResult {
972 AsynchronousSymbolQuerySet QueriesToFail;
973 std::shared_ptr<SymbolDependenceMap> FailedSymbols;
974 std::vector<std::unique_ptr<MaterializationUnit>> DefunctMUs;
975 };
976
977 RemoveTrackerResult IL_removeTracker(ResourceTracker &RT);
978
979 void transferTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT);
980
981 LLVM_ABI Error defineImpl(MaterializationUnit &MU);
982
983 LLVM_ABI void
984 installMaterializationUnit(std::unique_ptr<MaterializationUnit> MU,
985 ResourceTracker &RT);
986
987 void detachQueryHelper(AsynchronousSymbolQuery &Q,
988 const SymbolNameSet &QuerySymbols);
989
990 void transferEmittedNodeDependencies(MaterializingInfo &DependantMI,
991 const SymbolStringPtr &DependantName,
992 MaterializingInfo &EmittedMI);
993
994 Expected<SymbolFlagsMap>
995 defineMaterializing(MaterializationResponsibility &FromMR,
996 SymbolFlagsMap SymbolFlags);
997
998 Error replace(MaterializationResponsibility &FromMR,
999 std::unique_ptr<MaterializationUnit> MU);
1000
1001 Expected<std::unique_ptr<MaterializationResponsibility>>
1002 delegate(MaterializationResponsibility &FromMR, SymbolFlagsMap SymbolFlags,
1003 SymbolStringPtr InitSymbol);
1004
1005 SymbolNameSet getRequestedSymbols(const SymbolFlagsMap &SymbolFlags) const;
1006
1007 void addDependencies(const SymbolStringPtr &Name,
1008 const SymbolDependenceMap &Dependants);
1009
1011
1012 void unlinkMaterializationResponsibility(MaterializationResponsibility &MR);
1013
1014 /// Attempt to reduce memory usage from empty \c UnmaterializedInfos and
1015 /// \c MaterializingInfos tables.
1016 void shrinkMaterializationInfoMemory();
1017
1018 ExecutionSession &ES;
1019 enum { Open, Closing, Closed } State = Open;
1020 std::mutex GeneratorsMutex;
1021 SymbolTable Symbols;
1022 UnmaterializedInfosMap UnmaterializedInfos;
1023 MaterializingInfosMap MaterializingInfos;
1024 std::vector<std::shared_ptr<DefinitionGenerator>> DefGenerators;
1025 JITDylibSearchOrder LinkOrder;
1026 ResourceTrackerSP DefaultTracker;
1027
1028 // Map trackers to sets of symbols tracked.
1029 DenseMap<ResourceTracker *, SymbolNameVector> TrackerSymbols;
1030 DenseMap<ResourceTracker *, DenseSet<MaterializationResponsibility *>>
1031 TrackerMRs;
1032};
1033
1034/// Platforms set up standard symbols and mediate interactions between dynamic
1035/// initializers (e.g. C++ static constructors) and ExecutionSession state.
1036/// Note that Platforms do not automatically run initializers: clients are still
1037/// responsible for doing this.
1039public:
1040 virtual ~Platform();
1041
1042 /// This method will be called outside the session lock each time a JITDylib
1043 /// is created (unless it is created with EmptyJITDylib set) to allow the
1044 /// Platform to install any JITDylib specific standard symbols (e.g
1045 /// __dso_handle).
1046 virtual Error setupJITDylib(JITDylib &JD) = 0;
1047
1048 /// This method will be called outside the session lock each time a JITDylib
1049 /// is removed to allow the Platform to remove any JITDylib-specific data.
1051
1052 /// This method will be called under the ExecutionSession lock each time a
1053 /// MaterializationUnit is added to a JITDylib.
1055 const MaterializationUnit &MU) = 0;
1056
1057 /// This method will be called under the ExecutionSession lock when a
1058 /// ResourceTracker is removed.
1060
1061 /// A utility function for looking up initializer symbols. Performs a blocking
1062 /// lookup for the given symbols in each of the given JITDylibs.
1063 ///
1064 /// Note: This function is deprecated and will be removed in the near future.
1068
1069 /// Performs an async lookup for the given symbols in each of the given
1070 /// JITDylibs, calling the given handler once all lookups have completed.
1071 static void
1073 ExecutionSession &ES,
1075};
1076
1077/// A materialization task.
1079 : public RTTIExtends<MaterializationTask, Task> {
1080public:
1081 static char ID;
1082
1083 MaterializationTask(std::unique_ptr<MaterializationUnit> MU,
1084 std::unique_ptr<MaterializationResponsibility> MR)
1085 : MU(std::move(MU)), MR(std::move(MR)) {}
1086 ~MaterializationTask() override;
1087 void printDescription(raw_ostream &OS) override;
1088 void run() override;
1089
1090private:
1091 std::unique_ptr<MaterializationUnit> MU;
1092 std::unique_ptr<MaterializationResponsibility> MR;
1093};
1094
1095/// Lookups are usually run on the current thread, but in some cases they may
1096/// be run as tasks, e.g. if the lookup has been continued from a suspended
1097/// state.
1098class LLVM_ABI LookupTask : public RTTIExtends<LookupTask, Task> {
1099public:
1100 static char ID;
1101
1102 LookupTask(LookupState LS) : LS(std::move(LS)) {}
1103 void printDescription(raw_ostream &OS) override;
1104 void run() override;
1105
1106private:
1107 LookupState LS;
1108};
1109
1110/// An ExecutionSession represents a running JIT program.
1114 friend class JITDylib;
1115 friend class LookupState;
1117 friend class ResourceTracker;
1118
1119public:
1120 /// For reporting errors.
1122
1123 /// Send a result to the remote.
1125
1126 /// An asynchronous wrapper-function callable from the executor via
1127 /// jit-dispatch.
1129 SendResultFunction SendResult,
1130 const char *ArgData, size_t ArgSize)>;
1131
1132 /// A map associating tag names with asynchronous wrapper function
1133 /// implementations in the JIT.
1136
1137 /// Construct an ExecutionSession with the given ExecutorProcessControl
1138 /// object.
1139 LLVM_ABI ExecutionSession(std::unique_ptr<ExecutorProcessControl> EPC);
1140
1141 /// Destroy an ExecutionSession. Verifies that endSession was called prior to
1142 /// destruction.
1144
1145 /// End the session. Closes all JITDylibs and disconnects from the
1146 /// executor. Clients must call this method before destroying the session.
1148
1149 /// Get the ExecutorProcessControl object associated with this
1150 /// ExecutionSession.
1152
1153 /// Return the triple for the executor.
1154 const Triple &getTargetTriple() const { return EPC->getTargetTriple(); }
1155
1156 // Return the page size for the executor.
1157 size_t getPageSize() const { return EPC->getPageSize(); }
1158
1159 /// Get the SymbolStringPool for this instance.
1160 std::shared_ptr<SymbolStringPool> getSymbolStringPool() {
1161 return EPC->getSymbolStringPool();
1162 }
1163
1164 /// Add a symbol name to the SymbolStringPool and return a pointer to it.
1165 SymbolStringPtr intern(StringRef SymName) { return EPC->intern(SymName); }
1166
1167 /// Returns a reference to the bootstrap JITDylib.
1168 ///
1169 /// This is a bare JITDylib that is created for each ExecutionSession and
1170 /// populated with the bootstrap symbol definitions provided by the
1171 /// ExecutorProcessControl object.
1172 JITDylib &getBootstrapJITDylib() { return BootstrapJD; }
1173
1174 /// Set a WaitingOnGraph::Recorder to capture WaitingOnGraph operations.
1175 ///
1176 /// This method can be called at most once. If called, it should be called
1177 /// before any symbols are materialized.
1178 void setWaitingOnGraphOpRecorder(WaitingOnGraph::OpRecorder &R) {
1179 assert(!GOpRecorder && "WaitingOnGraph recorder already set");
1180 GOpRecorder = &R;
1181 }
1182
1183 /// Set the Platform for this ExecutionSession.
1184 void setPlatform(std::unique_ptr<Platform> P) { this->P = std::move(P); }
1185
1186 /// Get the Platform for this session.
1187 /// Will return null if no Platform has been set for this ExecutionSession.
1188 Platform *getPlatform() { return P.get(); }
1189
1190 /// Run the given lambda with the session mutex locked.
1191 template <typename Func> decltype(auto) runSessionLocked(Func &&F) {
1192 std::lock_guard<std::recursive_mutex> Lock(SessionMutex);
1193 return F();
1194 }
1195
1196 /// Register the given ResourceManager with this ExecutionSession.
1197 /// Managers will be notified of events in reverse order of registration.
1199
1200 /// Deregister the given ResourceManager with this ExecutionSession.
1201 /// Manager must have been previously registered.
1203
1204 /// Return a pointer to the "name" JITDylib.
1205 /// Ownership of JITDylib remains within Execution Session
1207
1208 /// Add a new bare JITDylib to this ExecutionSession.
1209 ///
1210 /// The JITDylib Name is required to be unique. Clients should verify that
1211 /// names are not being re-used (E.g. by calling getJITDylibByName) if names
1212 /// are based on user input.
1213 ///
1214 /// This call does not install any library code or symbols into the newly
1215 /// created JITDylib. The client is responsible for all configuration.
1216 LLVM_ABI JITDylib &createBareJITDylib(std::string Name);
1217
1218 /// Add a new JITDylib to this ExecutionSession.
1219 ///
1220 /// The JITDylib Name is required to be unique. Clients should verify that
1221 /// names are not being re-used (e.g. by calling getJITDylibByName) if names
1222 /// are based on user input.
1223 ///
1224 /// If a Platform is attached then Platform::setupJITDylib will be called to
1225 /// install standard platform symbols (e.g. standard library interposes).
1226 /// If no Platform is attached this call is equivalent to createBareJITDylib.
1228
1229 /// Removes the given JITDylibs from the ExecutionSession.
1230 ///
1231 /// This method clears all resources held for the JITDylibs, puts them in the
1232 /// closed state, and clears all references to them that are held by the
1233 /// ExecutionSession or other JITDylibs. No further code can be added to the
1234 /// removed JITDylibs, and the JITDylib objects will be freed once any
1235 /// remaining JITDylibSPs pointing to them are destroyed.
1236 ///
1237 /// This method does *not* run static destructors for code contained in the
1238 /// JITDylibs, and each JITDylib can only be removed once.
1239 ///
1240 /// JITDylibs will be removed in the order given. Teardown is usually
1241 /// independent for each JITDylib, but not always. In particular, where the
1242 /// ORC runtime is used it is expected that teardown off all JITDylibs will
1243 /// depend on it, so the JITDylib containing the ORC runtime must be removed
1244 /// last. If the client has introduced any other dependencies they should be
1245 /// accounted for in the removal order too.
1246 LLVM_ABI Error removeJITDylibs(std::vector<JITDylibSP> JDsToRemove);
1247
1248 /// Calls removeJTIDylibs on the gives JITDylib.
1250 return removeJITDylibs(std::vector<JITDylibSP>({&JD}));
1251 }
1252
1253 /// Set the error reporter function.
1255 this->ReportError = std::move(ReportError);
1256 return *this;
1257 }
1258
1259 /// Report a error for this execution session.
1260 ///
1261 /// Unhandled errors can be sent here to log them.
1262 void reportError(Error Err) { ReportError(std::move(Err)); }
1263
1264 /// Search the given JITDylibs to find the flags associated with each of the
1265 /// given symbols.
1266 LLVM_ABI void
1268 SymbolLookupSet Symbols,
1269 unique_function<void(Expected<SymbolFlagsMap>)> OnComplete);
1270
1271 /// Blocking version of lookupFlags.
1273 JITDylibSearchOrder SearchOrder,
1274 SymbolLookupSet Symbols);
1275
1276 /// Search the given JITDylibs for the given symbols.
1277 ///
1278 /// SearchOrder lists the JITDylibs to search. For each dylib, the associated
1279 /// boolean indicates whether the search should match against non-exported
1280 /// (hidden visibility) symbols in that dylib (true means match against
1281 /// non-exported symbols, false means do not match).
1282 ///
1283 /// The NotifyComplete callback will be called once all requested symbols
1284 /// reach the required state.
1285 ///
1286 /// If all symbols are found, the RegisterDependencies function will be called
1287 /// while the session lock is held. This gives clients a chance to register
1288 /// dependencies for on the queried symbols for any symbols they are
1289 /// materializing (if a MaterializationResponsibility instance is present,
1290 /// this can be implemented by calling
1291 /// MaterializationResponsibility::addDependencies). If there are no
1292 /// dependenant symbols for this query (e.g. it is being made by a top level
1293 /// client to get an address to call) then the value NoDependenciesToRegister
1294 /// can be used.
1295 LLVM_ABI void lookup(LookupKind K, const JITDylibSearchOrder &SearchOrder,
1296 SymbolLookupSet Symbols, SymbolState RequiredState,
1297 SymbolsResolvedCallback NotifyComplete,
1298 RegisterDependenciesFunction RegisterDependencies);
1299
1300 /// Blocking version of lookup above. Returns the resolved symbol map.
1301 /// If WaitUntilReady is true (the default), will not return until all
1302 /// requested symbols are ready (or an error occurs). If WaitUntilReady is
1303 /// false, will return as soon as all requested symbols are resolved,
1304 /// or an error occurs. If WaitUntilReady is false and an error occurs
1305 /// after resolution, the function will return a success value, but the
1306 /// error will be reported via reportErrors.
1308 lookup(const JITDylibSearchOrder &SearchOrder, SymbolLookupSet Symbols,
1310 SymbolState RequiredState = SymbolState::Ready,
1311 RegisterDependenciesFunction RegisterDependencies =
1313
1314 /// Convenience version of blocking lookup.
1315 /// Searches each of the JITDylibs in the search order in turn for the given
1316 /// symbol.
1318 lookup(const JITDylibSearchOrder &SearchOrder, SymbolStringPtr Symbol,
1319 SymbolState RequiredState = SymbolState::Ready);
1320
1321 /// Convenience version of blocking lookup.
1322 /// Searches each of the JITDylibs in the search order in turn for the given
1323 /// symbol. The search will not find non-exported symbols.
1325 lookup(ArrayRef<JITDylib *> SearchOrder, SymbolStringPtr Symbol,
1326 SymbolState RequiredState = SymbolState::Ready);
1327
1328 /// Convenience version of blocking lookup.
1329 /// Searches each of the JITDylibs in the search order in turn for the given
1330 /// symbol. The search will not find non-exported symbols.
1332 lookup(ArrayRef<JITDylib *> SearchOrder, StringRef Symbol,
1333 SymbolState RequiredState = SymbolState::Ready);
1334
1335 /// Materialize the given unit.
1336 void dispatchTask(std::unique_ptr<Task> T) {
1337 assert(T && "T must be non-null");
1338 DEBUG_WITH_TYPE("orc", dumpDispatchInfo(*T));
1339 EPC->getDispatcher().dispatch(std::move(T));
1340 }
1341
1342 /// Returns the bootstrap map.
1344 return EPC->getBootstrapMap();
1345 }
1346
1347 /// Look up and SPS-deserialize a bootstrap map value.
1348 template <typename T, typename SPSTagT>
1349 Error getBootstrapMapValue(StringRef Key, std::optional<T> &Val) const {
1350 return EPC->getBootstrapMapValue<T, SPSTagT>(Key, Val);
1351 }
1352
1353 /// Returns the bootstrap symbol map.
1355 return EPC->getBootstrapSymbolsMap();
1356 }
1357
1358 /// For each (ExecutorAddr&, StringRef) pair, looks up the string in the
1359 /// bootstrap symbols map and writes its address to the ExecutorAddr if
1360 /// found. If any symbol is not found then the function returns an error.
1362 ArrayRef<std::pair<ExecutorAddr &, StringRef>> Pairs) const {
1363 return EPC->getBootstrapSymbols(Pairs);
1364 }
1365
1366 /// Run a wrapper function in the executor. The given WFRHandler will be
1367 /// called on the result when it is returned.
1368 ///
1369 /// The wrapper function should be callable as:
1370 ///
1371 /// \code{.cpp}
1372 /// CWrapperFunctionBuffer fn(uint8_t *Data, uint64_t Size);
1373 /// \endcode{.cpp}
1374 void callWrapperAsync(ExecutorAddr WrapperFnAddr,
1376 ArrayRef<char> ArgBuffer) {
1377 EPC->callWrapperAsync(WrapperFnAddr, std::move(OnComplete), ArgBuffer);
1378 }
1379
1380 /// Run a wrapper function in the executor using the given Runner to dispatch
1381 /// OnComplete when the result is ready.
1382 template <typename RunPolicyT, typename FnT>
1383 void callWrapperAsync(RunPolicyT &&Runner, ExecutorAddr WrapperFnAddr,
1384 FnT &&OnComplete, ArrayRef<char> ArgBuffer) {
1385 EPC->callWrapperAsync(std::forward<RunPolicyT>(Runner), WrapperFnAddr,
1386 std::forward<FnT>(OnComplete), ArgBuffer);
1387 }
1388
1389 /// Run a wrapper function in the executor. OnComplete will be dispatched
1390 /// as a GenericNamedTask using this instance's TaskDispatch object.
1391 template <typename FnT>
1392 void callWrapperAsync(ExecutorAddr WrapperFnAddr, FnT &&OnComplete,
1393 ArrayRef<char> ArgBuffer) {
1394 EPC->callWrapperAsync(WrapperFnAddr, std::forward<FnT>(OnComplete),
1395 ArgBuffer);
1396 }
1397
1398 /// Run a wrapper function in the executor. The wrapper function should be
1399 /// callable as:
1400 ///
1401 /// \code{.cpp}
1402 /// CWrapperFunctionBuffer fn(uint8_t *Data, uint64_t Size);
1403 /// \endcode{.cpp}
1405 ArrayRef<char> ArgBuffer) {
1406 return EPC->callWrapper(WrapperFnAddr, ArgBuffer);
1407 }
1408
1409 /// Run a wrapper function using SPS to serialize the arguments and
1410 /// deserialize the results.
1411 template <typename SPSSignature, typename SendResultT, typename... ArgTs>
1412 void callSPSWrapperAsync(ExecutorAddr WrapperFnAddr, SendResultT &&SendResult,
1413 const ArgTs &...Args) {
1414 EPC->callSPSWrapperAsync<SPSSignature, SendResultT, ArgTs...>(
1415 WrapperFnAddr, std::forward<SendResultT>(SendResult), Args...);
1416 }
1417
1418 /// Run a wrapper function using SPS to serialize the arguments and
1419 /// deserialize the results.
1420 ///
1421 /// If SPSSignature is a non-void function signature then the second argument
1422 /// (the first in the Args list) should be a reference to a return value.
1423 template <typename SPSSignature, typename... WrapperCallArgTs>
1425 WrapperCallArgTs &&...WrapperCallArgs) {
1426 return EPC->callSPSWrapper<SPSSignature, WrapperCallArgTs...>(
1427 WrapperFnAddr, std::forward<WrapperCallArgTs>(WrapperCallArgs)...);
1428 }
1429
1430 /// Wrap a handler that takes concrete argument types (and a sender for a
1431 /// concrete return type) to produce an AsyncHandlerWrapperFunction. Uses SPS
1432 /// to unpack the arguments and pack the result.
1433 ///
1434 /// This function is intended to support easy construction of
1435 /// AsyncHandlerWrapperFunctions that can be associated with a tag
1436 /// (using registerJITDispatchHandler) and called from the executor.
1437 template <typename SPSSignature, typename HandlerT>
1439 return [H = std::forward<HandlerT>(H)](SendResultFunction SendResult,
1440 const char *ArgData,
1441 size_t ArgSize) mutable {
1443 ArgData, ArgSize, std::move(SendResult), H);
1444 };
1445 }
1446
1447 /// Wrap a class method that takes concrete argument types (and a sender for
1448 /// a concrete return type) to produce an AsyncHandlerWrapperFunction. Uses
1449 /// SPS to unpack the arguments and pack the result.
1450 ///
1451 /// This function is intended to support easy construction of
1452 /// AsyncHandlerWrapperFunctions that can be associated with a tag
1453 /// (using registerJITDispatchHandler) and called from the executor.
1454 template <typename SPSSignature, typename ClassT, typename... MethodArgTs>
1456 wrapAsyncWithSPS(ClassT *Instance, void (ClassT::*Method)(MethodArgTs...)) {
1458 [Instance, Method](MethodArgTs &&...MethodArgs) {
1459 (Instance->*Method)(std::forward<MethodArgTs>(MethodArgs)...);
1460 });
1461 }
1462
1463 /// For each tag symbol name, associate the corresponding
1464 /// AsyncHandlerWrapperFunction with the address of that symbol. The
1465 /// handler becomes callable from the executor using the ORC runtime
1466 /// __orc_rt_jit_dispatch function and the given tag.
1467 ///
1468 /// Tag symbols will be looked up in JD using LookupKind::Static,
1469 /// JITDylibLookupFlags::MatchAllSymbols (hidden tags will be found), and
1470 /// LookupFlags::WeaklyReferencedSymbol. Missing tag definitions will not
1471 /// cause an error, the handler will simply be dropped.
1474
1475 /// Run a registered jit-side wrapper function.
1476 /// This should be called by the ExecutorProcessControl instance in response
1477 /// to incoming jit-dispatch requests from the executor.
1479 ExecutorAddr HandlerFnTagAddr,
1481
1482 /// Dump the state of all the JITDylibs in this session.
1483 LLVM_ABI void dump(raw_ostream &OS);
1484
1485 /// Check the internal consistency of ExecutionSession data structures.
1486#ifdef EXPENSIVE_CHECKS
1487 bool verifySessionState(Twine Phase);
1488#endif
1489
1490private:
1491 static void logErrorsToStdErr(Error Err) {
1492 logAllUnhandledErrors(std::move(Err), errs(), "JIT session error: ");
1493 }
1494
1495 void dispatchOutstandingMUs();
1496
1497 static std::unique_ptr<MaterializationResponsibility>
1498 createMaterializationResponsibility(ResourceTracker &RT,
1499 SymbolFlagsMap Symbols,
1500 SymbolStringPtr InitSymbol) {
1501 auto &JD = RT.getJITDylib();
1502 std::unique_ptr<MaterializationResponsibility> MR(
1503 new MaterializationResponsibility(&RT, std::move(Symbols),
1504 std::move(InitSymbol)));
1505 JD.TrackerMRs[&RT].insert(MR.get());
1506 return MR;
1507 }
1508
1509 Error removeResourceTracker(ResourceTracker &RT);
1510 void transferResourceTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT);
1511 void destroyResourceTracker(ResourceTracker &RT);
1512
1513 // State machine functions for query application..
1514
1515 /// IL_updateCandidatesFor is called to remove already-defined symbols that
1516 /// match a given query from the set of candidate symbols to generate
1517 /// definitions for (no need to generate a definition if one already exists).
1518 Error IL_updateCandidatesFor(JITDylib &JD, JITDylibLookupFlags JDLookupFlags,
1519 SymbolLookupSet &Candidates,
1520 SymbolLookupSet *NonCandidates);
1521
1522 /// Handle resumption of a lookup after entering a generator.
1523 void OL_resumeLookupAfterGeneration(InProgressLookupState &IPLS);
1524
1525 /// OL_applyQueryPhase1 is an optionally re-startable loop for triggering
1526 /// definition generation. It is called when a lookup is performed, and again
1527 /// each time that LookupState::continueLookup is called.
1528 void OL_applyQueryPhase1(std::unique_ptr<InProgressLookupState> IPLS,
1529 Error Err);
1530
1531 /// OL_completeLookup is run once phase 1 successfully completes for a lookup
1532 /// call. It attempts to attach the symbol to all symbol table entries and
1533 /// collect all MaterializationUnits to dispatch. If this method fails then
1534 /// all MaterializationUnits will be left un-materialized.
1535 void OL_completeLookup(std::unique_ptr<InProgressLookupState> IPLS,
1536 std::shared_ptr<AsynchronousSymbolQuery> Q,
1537 RegisterDependenciesFunction RegisterDependencies);
1538
1539 /// OL_completeLookupFlags is run once phase 1 successfully completes for a
1540 /// lookupFlags call.
1541 void OL_completeLookupFlags(
1542 std::unique_ptr<InProgressLookupState> IPLS,
1543 unique_function<void(Expected<SymbolFlagsMap>)> OnComplete);
1544
1545 // State machine functions for MaterializationResponsibility.
1546 LLVM_ABI void
1547 OL_destroyMaterializationResponsibility(MaterializationResponsibility &MR);
1549 OL_getRequestedSymbols(const MaterializationResponsibility &MR);
1550 LLVM_ABI Error OL_notifyResolved(MaterializationResponsibility &MR,
1551 const SymbolMap &Symbols);
1552
1553 // FIXME: We should be able to derive FailedSymsForQuery from each query once
1554 // we fix how the detach operation works.
1555 struct EmitQueries {
1556 JITDylib::AsynchronousSymbolQuerySet Completed;
1557 JITDylib::AsynchronousSymbolQuerySet Failed;
1558 DenseMap<AsynchronousSymbolQuery *, std::shared_ptr<SymbolDependenceMap>>
1559 FailedSymsForQuery;
1560 };
1561
1563 IL_getSymbolState(JITDylib *JD, NonOwningSymbolStringPtr Name);
1564
1565 template <typename UpdateSymbolFn, typename UpdateQueryFn>
1566 void IL_collectQueries(JITDylib::AsynchronousSymbolQuerySet &Qs,
1567 WaitingOnGraph::ContainerElementsMap &QualifiedSymbols,
1568 UpdateSymbolFn &&UpdateSymbol,
1569 UpdateQueryFn &&UpdateQuery);
1570
1571 Expected<EmitQueries> IL_emit(MaterializationResponsibility &MR,
1572 WaitingOnGraph::SimplifyResult SR);
1573 LLVM_ABI Error OL_notifyEmitted(MaterializationResponsibility &MR,
1575
1576 LLVM_ABI Error OL_defineMaterializing(MaterializationResponsibility &MR,
1577 SymbolFlagsMap SymbolFlags);
1578
1579 std::pair<JITDylib::AsynchronousSymbolQuerySet,
1580 std::shared_ptr<SymbolDependenceMap>>
1581 IL_failSymbols(JITDylib &JD, const SymbolNameVector &SymbolsToFail);
1582 LLVM_ABI void OL_notifyFailed(MaterializationResponsibility &MR);
1584 std::unique_ptr<MaterializationUnit> MU);
1585 LLVM_ABI Expected<std::unique_ptr<MaterializationResponsibility>>
1586 OL_delegate(MaterializationResponsibility &MR, const SymbolNameSet &Symbols);
1587
1588#ifndef NDEBUG
1589 void dumpDispatchInfo(Task &T);
1590#endif // NDEBUG
1591
1592 mutable std::recursive_mutex SessionMutex;
1593 bool SessionOpen = true;
1594 std::unique_ptr<ExecutorProcessControl> EPC;
1595 std::unique_ptr<Platform> P;
1596 ErrorReporter ReportError = logErrorsToStdErr;
1597
1598 std::vector<ResourceManager *> ResourceManagers;
1599
1600 std::vector<JITDylibSP> JDs;
1601 JITDylib &BootstrapJD;
1603 WaitingOnGraph::OpRecorder *GOpRecorder = nullptr;
1604
1605 // FIXME: Remove this (and runOutstandingMUs) once the linking layer works
1606 // with callbacks from asynchronous queries.
1607 mutable std::recursive_mutex OutstandingMUsMutex;
1608 std::vector<std::pair<std::unique_ptr<MaterializationUnit>,
1609 std::unique_ptr<MaterializationResponsibility>>>
1610 OutstandingMUs;
1611
1612 mutable std::mutex JITDispatchHandlersMutex;
1613 DenseMap<ExecutorAddr, std::shared_ptr<JITDispatchHandlerFunction>>
1614 JITDispatchHandlers;
1615};
1616
1617template <typename Func> Error ResourceTracker::withResourceKeyDo(Func &&F) {
1619 if (isDefunct())
1621 F(getKeyUnsafe());
1622 return Error::success();
1623 });
1624}
1625
1626inline ExecutionSession &
1628 return JD.getExecutionSession();
1629}
1630
1631template <typename GeneratorT>
1632GeneratorT &JITDylib::addGenerator(std::unique_ptr<GeneratorT> DefGenerator) {
1633 auto &G = *DefGenerator;
1634 ES.runSessionLocked([&] {
1635 assert(State == Open && "Cannot add generator to closed JITDylib");
1636 DefGenerators.push_back(std::move(DefGenerator));
1637 });
1638 return G;
1639}
1640
1641template <typename Func>
1643 -> decltype(F(std::declval<const JITDylibSearchOrder &>())) {
1644 assert(State == Open && "Cannot use link order of closed JITDylib");
1645 return ES.runSessionLocked([&]() { return F(LinkOrder); });
1646}
1647
1648template <typename MaterializationUnitType>
1649Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &&MU,
1650 ResourceTrackerSP RT) {
1651 assert(MU && "Can not define with a null MU");
1652
1653 if (MU->getSymbols().empty()) {
1654 // Empty MUs are allowable but pathological, so issue a warning.
1655 DEBUG_WITH_TYPE("orc", {
1656 dbgs() << "Warning: Discarding empty MU " << MU->getName() << " for "
1657 << getName() << "\n";
1658 });
1659 return Error::success();
1660 } else
1661 DEBUG_WITH_TYPE("orc", {
1662 dbgs() << "Defining MU " << MU->getName() << " for " << getName()
1663 << " (tracker: ";
1664 if (RT == getDefaultResourceTracker())
1665 dbgs() << "default)";
1666 else if (RT)
1667 dbgs() << RT.get() << ")\n";
1668 else
1669 dbgs() << "0x0, default will be used)\n";
1670 });
1671
1672 return ES.runSessionLocked([&, this]() -> Error {
1673 if (State != Open)
1674 return make_error<JITDylibDefunct>(this);
1675
1676 if (auto Err = defineImpl(*MU))
1677 return Err;
1678
1679 if (!RT)
1681
1682 if (auto *P = ES.getPlatform()) {
1683 if (auto Err = P->notifyAdding(*RT, *MU))
1684 return Err;
1685 }
1686
1687 installMaterializationUnit(std::move(MU), *RT);
1688 return Error::success();
1689 });
1690}
1691
1692template <typename MaterializationUnitType>
1693Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &MU,
1694 ResourceTrackerSP RT) {
1695 assert(MU && "Can not define with a null MU");
1696
1697 if (MU->getSymbols().empty()) {
1698 // Empty MUs are allowable but pathological, so issue a warning.
1699 DEBUG_WITH_TYPE("orc", {
1700 dbgs() << "Warning: Discarding empty MU " << MU->getName() << getName()
1701 << "\n";
1702 });
1703 return Error::success();
1704 } else
1705 DEBUG_WITH_TYPE("orc", {
1706 dbgs() << "Defining MU " << MU->getName() << " for " << getName()
1707 << " (tracker: ";
1708 if (RT == getDefaultResourceTracker())
1709 dbgs() << "default)";
1710 else if (RT)
1711 dbgs() << RT.get() << ")\n";
1712 else
1713 dbgs() << "0x0, default will be used)\n";
1714 });
1715
1716 return ES.runSessionLocked([&, this]() -> Error {
1717 assert(State == Open && "JD is defunct");
1718
1719 if (auto Err = defineImpl(*MU))
1720 return Err;
1721
1722 if (!RT)
1724
1725 if (auto *P = ES.getPlatform()) {
1726 if (auto Err = P->notifyAdding(*RT, *MU))
1727 return Err;
1728 }
1729
1730 installMaterializationUnit(std::move(MU), *RT);
1731 return Error::success();
1732 });
1733}
1734
1735/// ReexportsGenerator can be used with JITDylib::addGenerator to automatically
1736/// re-export a subset of the source JITDylib's symbols in the target.
1738public:
1739 using SymbolPredicate = std::function<bool(SymbolStringPtr)>;
1740
1741 /// Create a reexports generator. If an Allow predicate is passed, only
1742 /// symbols for which the predicate returns true will be reexported. If no
1743 /// Allow predicate is passed, all symbols will be exported.
1744 ReexportsGenerator(JITDylib &SourceJD,
1745 JITDylibLookupFlags SourceJDLookupFlags,
1747
1749 JITDylibLookupFlags JDLookupFlags,
1750 const SymbolLookupSet &LookupSet) override;
1751
1752private:
1753 JITDylib &SourceJD;
1754 JITDylibLookupFlags SourceJDLookupFlags;
1755 SymbolPredicate Allow;
1756};
1757
1758// --------------- IMPLEMENTATION --------------
1759// Implementations for inline functions/methods.
1760// ---------------------------------------------
1761
1763 getExecutionSession().OL_destroyMaterializationResponsibility(*this);
1764}
1765
1767 return getExecutionSession().OL_getRequestedSymbols(*this);
1768}
1769
1771 const SymbolMap &Symbols) {
1772 return getExecutionSession().OL_notifyResolved(*this, Symbols);
1773}
1774
1776 ArrayRef<SymbolDependenceGroup> EmittedDeps) {
1777 return getExecutionSession().OL_notifyEmitted(*this, EmittedDeps);
1778}
1779
1781 SymbolFlagsMap SymbolFlags) {
1782 return getExecutionSession().OL_defineMaterializing(*this,
1783 std::move(SymbolFlags));
1784}
1785
1787 getExecutionSession().OL_notifyFailed(*this);
1788}
1789
1791 std::unique_ptr<MaterializationUnit> MU) {
1792 return getExecutionSession().OL_replace(*this, std::move(MU));
1793}
1794
1797 return getExecutionSession().OL_delegate(*this, Symbols);
1798}
1799
1800} // End namespace orc
1801} // End namespace llvm
1802
1803#endif // LLVM_EXECUTIONENGINE_ORC_CORE_H
aarch64 falkor hwpf fix Falkor HW Prefetch Fix Late Phase
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Function Alias Analysis false
#define LLVM_ABI
Definition Compiler.h:215
This file defines the DenseSet and SmallDenseSet classes.
This file provides a collection of function (or more generally, callable) type erasure utilities supp...
This file defines the RefCountedBase, ThreadSafeRefCountedBase, and IntrusiveRefCntPtr classes.
#define F(x, y, z)
Definition MD5.cpp:54
#define G(x, y, z)
Definition MD5.cpp:55
#define H(x, y, z)
Definition MD5.cpp:56
#define T
#define P(N)
static StringRef getName(Value *V)
#define DEBUG_WITH_TYPE(TYPE,...)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
Definition Debug.h:72
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Definition DenseMap.h:171
Base class for user error types.
Definition Error.h:354
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
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
Flags for symbols in the JIT.
Definition JITSymbol.h:75
Inheritance utility for extensible RTTI.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:128
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
A symbol query that returns results via a callback when results are ready.
Definition Core.h:558
LLVM_ABI AsynchronousSymbolQuery(const SymbolLookupSet &Symbols, SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete)
Create a query for the given symbols.
Definition Core.cpp:191
bool isComplete() const
Returns true if all symbols covered by this query have been resolved.
Definition Core.h:579
friend class InProgressFullLookupState
Definition Core.h:560
LLVM_ABI void notifySymbolMetRequiredState(const SymbolStringPtr &Name, ExecutorSymbolDef Sym)
Notify the query that a requested symbol has reached the required state.
Definition Core.cpp:205
friend class JITSymbolResolverAdapter
Definition Core.h:562
friend class MaterializationResponsibility
Definition Core.h:563
Definition generators can be attached to JITDylibs to generate new definitions for otherwise unresolv...
Definition Core.h:632
virtual Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD, JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &LookupSet)=0
DefinitionGenerators should override this method to insert new definitions into the parent JITDylib.
friend class ExecutionSession
Definition Core.h:633
An ExecutionSession represents a running JIT program.
Definition Core.h:1111
LLVM_ABI void runJITDispatchHandler(SendResultFunction SendResult, ExecutorAddr HandlerFnTagAddr, shared::WrapperFunctionBuffer ArgBytes)
Run a registered jit-side wrapper function.
Definition Core.cpp:1898
LLVM_ABI Error endSession()
End the session.
Definition Core.cpp:1572
ExecutorProcessControl & getExecutorProcessControl()
Get the ExecutorProcessControl object associated with this ExecutionSession.
Definition Core.h:1151
shared::WrapperFunctionBuffer callWrapper(ExecutorAddr WrapperFnAddr, ArrayRef< char > ArgBuffer)
Run a wrapper function in the executor.
Definition Core.h:1404
void reportError(Error Err)
Report a error for this execution session.
Definition Core.h:1262
void callWrapperAsync(ExecutorAddr WrapperFnAddr, ExecutorProcessControl::IncomingWFRHandler OnComplete, ArrayRef< char > ArgBuffer)
Run a wrapper function in the executor.
Definition Core.h:1374
friend class JITDylib
Definition Core.h:1114
friend class InProgressLookupFlagsState
Definition Core.h:1112
const StringMap< ExecutorAddr > & getBootstrapSymbolsMap() const
Returns the bootstrap symbol map.
Definition Core.h:1354
void setPlatform(std::unique_ptr< Platform > P)
Set the Platform for this ExecutionSession.
Definition Core.h:1184
const Triple & getTargetTriple() const
Return the triple for the executor.
Definition Core.h:1154
Platform * getPlatform()
Get the Platform for this session.
Definition Core.h:1188
Error callSPSWrapper(ExecutorAddr WrapperFnAddr, WrapperCallArgTs &&...WrapperCallArgs)
Run a wrapper function using SPS to serialize the arguments and deserialize the results.
Definition Core.h:1424
LLVM_ABI void lookupFlags(LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet Symbols, unique_function< void(Expected< SymbolFlagsMap >)> OnComplete)
Search the given JITDylibs to find the flags associated with each of the given symbols.
Definition Core.cpp:1738
SymbolStringPtr intern(StringRef SymName)
Add a symbol name to the SymbolStringPool and return a pointer to it.
Definition Core.h:1165
LLVM_ABI JITDylib * getJITDylibByName(StringRef Name)
Return a pointer to the "name" JITDylib.
Definition Core.cpp:1617
static JITDispatchHandlerFunction wrapAsyncWithSPS(ClassT *Instance, void(ClassT::*Method)(MethodArgTs...))
Wrap a class method that takes concrete argument types (and a sender for a concrete return type) to p...
Definition Core.h:1456
friend class LookupState
Definition Core.h:1115
void callWrapperAsync(RunPolicyT &&Runner, ExecutorAddr WrapperFnAddr, FnT &&OnComplete, ArrayRef< char > ArgBuffer)
Run a wrapper function in the executor using the given Runner to dispatch OnComplete when the result ...
Definition Core.h:1383
LLVM_ABI JITDylib & createBareJITDylib(std::string Name)
Add a new bare JITDylib to this ExecutionSession.
Definition Core.cpp:1626
static JITDispatchHandlerFunction wrapAsyncWithSPS(HandlerT &&H)
Wrap a handler that takes concrete argument types (and a sender for a concrete return type) to produc...
Definition Core.h:1438
void callSPSWrapperAsync(ExecutorAddr WrapperFnAddr, SendResultT &&SendResult, const ArgTs &...Args)
Run a wrapper function using SPS to serialize the arguments and deserialize the results.
Definition Core.h:1412
JITDylib & getBootstrapJITDylib()
Returns a reference to the bootstrap JITDylib.
Definition Core.h:1172
std::shared_ptr< SymbolStringPool > getSymbolStringPool()
Get the SymbolStringPool for this instance.
Definition Core.h:1160
Error getBootstrapMapValue(StringRef Key, std::optional< T > &Val) const
Look up and SPS-deserialize a bootstrap map value.
Definition Core.h:1349
friend class InProgressFullLookupState
Definition Core.h:1113
Error getBootstrapSymbols(ArrayRef< std::pair< ExecutorAddr &, StringRef > > Pairs) const
For each (ExecutorAddr&, StringRef) pair, looks up the string in the bootstrap symbols map and writes...
Definition Core.h:1361
const StringMap< std::vector< char > > & getBootstrapMap() const
Returns the bootstrap map.
Definition Core.h:1343
LLVM_ABI void lookup(LookupKind K, const JITDylibSearchOrder &SearchOrder, SymbolLookupSet Symbols, SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete, RegisterDependenciesFunction RegisterDependencies)
Search the given JITDylibs for the given symbols.
Definition Core.cpp:1764
LLVM_ABI Error registerJITDispatchHandlers(JITDylib &JD, JITDispatchHandlerAssociationMap WFs)
For each tag symbol name, associate the corresponding AsyncHandlerWrapperFunction with the address of...
Definition Core.cpp:1859
friend class MaterializationResponsibility
Definition Core.h:1116
LLVM_ABI void registerResourceManager(ResourceManager &RM)
Register the given ResourceManager with this ExecutionSession.
Definition Core.cpp:1600
LLVM_ABI ~ExecutionSession()
Destroy an ExecutionSession.
Definition Core.cpp:1566
void setWaitingOnGraphOpRecorder(WaitingOnGraph::OpRecorder &R)
Set a WaitingOnGraph::Recorder to capture WaitingOnGraph operations.
Definition Core.h:1178
LLVM_ABI void deregisterResourceManager(ResourceManager &RM)
Deregister the given ResourceManager with this ExecutionSession.
Definition Core.cpp:1604
LLVM_ABI ExecutionSession(std::unique_ptr< ExecutorProcessControl > EPC)
Construct an ExecutionSession with the given ExecutorProcessControl object.
Definition Core.cpp:1553
decltype(auto) runSessionLocked(Func &&F)
Run the given lambda with the session mutex locked.
Definition Core.h:1191
unique_function< void( SendResultFunction SendResult, const char *ArgData, size_t ArgSize)> JITDispatchHandlerFunction
An asynchronous wrapper-function callable from the executor via jit-dispatch.
Definition Core.h:1128
LLVM_ABI void dump(raw_ostream &OS)
Dump the state of all the JITDylibs in this session.
Definition Core.cpp:1919
unique_function< void(shared::WrapperFunctionBuffer)> SendResultFunction
Send a result to the remote.
Definition Core.h:1124
friend class ResourceTracker
Definition Core.h:1117
ExecutionSession & setErrorReporter(ErrorReporter ReportError)
Set the error reporter function.
Definition Core.h:1254
LLVM_ABI Error removeJITDylibs(std::vector< JITDylibSP > JDsToRemove)
Removes the given JITDylibs from the ExecutionSession.
Definition Core.cpp:1643
size_t getPageSize() const
Definition Core.h:1157
LLVM_ABI Expected< JITDylib & > createJITDylib(std::string Name)
Add a new JITDylib to this ExecutionSession.
Definition Core.cpp:1635
void dispatchTask(std::unique_ptr< Task > T)
Materialize the given unit.
Definition Core.h:1336
unique_function< void(Error)> ErrorReporter
For reporting errors.
Definition Core.h:1121
Error removeJITDylib(JITDylib &JD)
Calls removeJTIDylibs on the gives JITDylib.
Definition Core.h:1249
void callWrapperAsync(ExecutorAddr WrapperFnAddr, FnT &&OnComplete, ArrayRef< char > ArgBuffer)
Run a wrapper function in the executor.
Definition Core.h:1392
DenseMap< SymbolStringPtr, JITDispatchHandlerFunction > JITDispatchHandlerAssociationMap
A map associating tag names with asynchronous wrapper function implementations in the JIT.
Definition Core.h:1134
Represents an address in the executor process.
A handler or incoming WrapperFunctionBuffers – either return values from callWrapper* calls,...
ExecutorProcessControl supports interaction with a JIT target process.
Represents a defining location for a JIT symbol.
FailedToMaterialize(std::shared_ptr< SymbolStringPool > SSP, std::shared_ptr< SymbolDependenceMap > Symbols)
Definition Core.cpp:93
const SymbolDependenceMap & getSymbols() const
Definition Core.h:223
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition Core.cpp:111
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition Core.cpp:115
JITDylibDefunct(JITDylibSP JD)
Definition Core.h:204
Represents a JIT'd dynamic library.
Definition Core.h:675
LLVM_ABI ~JITDylib()
Definition Core.cpp:642
LLVM_ABI Error remove(const SymbolNameSet &Names)
Tries to remove the given symbols.
Definition Core.cpp:1044
LLVM_ABI Error clear()
Calls remove on all trackers currently associated with this JITDylib.
Definition Core.cpp:646
JITDylib & operator=(JITDylib &&)=delete
LLVM_ABI void dump(raw_ostream &OS)
Dump current JITDylib state to OS.
Definition Core.cpp:1100
friend class AsynchronousSymbolQuery
Definition Core.h:676
LLVM_ABI void replaceInLinkOrder(JITDylib &OldJD, JITDylib &NewJD, JITDylibLookupFlags JDLookupFlags=JITDylibLookupFlags::MatchExportedSymbolsOnly)
Replace OldJD with NewJD in the link order if OldJD is present.
Definition Core.cpp:1020
Error define(std::unique_ptr< MaterializationUnitType > &&MU, ResourceTrackerSP RT=nullptr)
Define all symbols provided by the materialization unit to be part of this JITDylib.
Definition Core.h:1649
ExecutionSession & getExecutionSession() const
Get a reference to the ExecutionSession for this JITDylib.
Definition Core.h:694
LLVM_ABI void addToLinkOrder(const JITDylibSearchOrder &NewLinks)
Append the given JITDylibSearchOrder to the link order for this JITDylib (discarding any elements alr...
Definition Core.cpp:1004
LLVM_ABI ResourceTrackerSP createResourceTracker()
Create a resource tracker for this JITDylib.
Definition Core.cpp:670
auto withLinkOrderDo(Func &&F) -> decltype(F(std::declval< const JITDylibSearchOrder & >()))
Do something with the link order (run under the session lock).
Definition Core.h:1642
friend class MaterializationResponsibility
Definition Core.h:679
friend class Platform
Definition Core.h:678
LLVM_ABI void removeFromLinkOrder(JITDylib &JD)
Remove the given JITDylib from the link order for this JITDylib if it is present.
Definition Core.cpp:1032
LLVM_ABI void setLinkOrder(JITDylibSearchOrder NewSearchOrder, bool LinkAgainstThisJITDylibFirst=true)
Set the link order to be used when fixing up definitions in JITDylib.
Definition Core.cpp:989
LLVM_ABI Expected< std::vector< JITDylibSP > > getReverseDFSLinkOrder()
Rteurn this JITDylib and its transitive dependencies in reverse DFS order based on linkage relationsh...
Definition Core.cpp:1734
friend class ExecutionSession
Definition Core.h:677
LLVM_ABI ResourceTrackerSP getDefaultResourceTracker()
Get the default resource tracker for this JITDylib.
Definition Core.cpp:661
GeneratorT & addGenerator(std::unique_ptr< GeneratorT > DefGenerator)
Adds a definition generator to this JITDylib and returns a referenece to it.
Definition Core.h:1632
JITDylib(const JITDylib &)=delete
JITDylib & operator=(const JITDylib &)=delete
JITDylib(JITDylib &&)=delete
LLVM_ABI void removeGenerator(DefinitionGenerator &G)
Remove a definition generator from this JITDylib.
Definition Core.cpp:678
LLVM_ABI Expected< std::vector< JITDylibSP > > getDFSLinkOrder()
Return this JITDylib and its transitive dependencies in DFS order based on linkage relationships.
Definition Core.cpp:1730
Wraps state for a lookup-in-progress.
Definition Core.h:607
LLVM_ABI void continueLookup(Error Err)
Continue the lookup.
Definition Core.cpp:622
LLVM_ABI LookupState & operator=(LookupState &&)
friend class ExecutionSession
Definition Core.h:609
friend class OrcV2CAPIHelper
Definition Core.h:608
LLVM_ABI LookupState(LookupState &&)
LookupTask(LookupState LS)
Definition Core.h:1102
static char ID
Definition Core.h:1100
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Definition Core.h:349
MaterializationResponsibility & operator=(MaterializationResponsibility &&)=delete
ExecutionSession & getExecutionSession() const
Returns the ExecutionSession for this instance.
Definition Core.h:1627
Error notifyResolved(const SymbolMap &Symbols)
Notifies the target JITDylib that the given symbols have been resolved.
Definition Core.h:1770
~MaterializationResponsibility()
Destruct a MaterializationResponsibility instance.
Definition Core.h:1762
Error replace(std::unique_ptr< MaterializationUnit > MU)
Transfers responsibility to the given MaterializationUnit for all symbols defined by that Materializa...
Definition Core.h:1790
Error withResourceKeyDo(Func &&F) const
Runs the given callback under the session lock, passing in the associated ResourceKey.
Definition Core.h:368
Error defineMaterializing(SymbolFlagsMap SymbolFlags)
Attempt to claim responsibility for new definitions.
Definition Core.h:1780
SymbolNameSet getRequestedSymbols() const
Returns the names of any symbols covered by this MaterializationResponsibility object that have queri...
Definition Core.h:1766
Expected< std::unique_ptr< MaterializationResponsibility > > delegate(const SymbolNameSet &Symbols)
Delegates responsibility for the given symbols to the returned materialization responsibility.
Definition Core.h:1796
const ResourceTrackerSP & getResourceTracker() const
Return the ResourceTracker associated with this instance.
Definition Core.h:364
const SymbolStringPtr & getInitializerSymbol() const
Returns the initialization pseudo-symbol, if any.
Definition Core.h:388
MaterializationResponsibility(MaterializationResponsibility &&)=delete
Error notifyEmitted(ArrayRef< SymbolDependenceGroup > DepGroups)
Notifies the target JITDylib (and any pending queries on that JITDylib) that all symbols covered by t...
Definition Core.h:1775
void failMaterialization()
Notify all not-yet-emitted covered by this MaterializationResponsibility instance that an error has o...
Definition Core.h:1786
JITDylib & getTargetJITDylib() const
Returns the target JITDylib that these symbols are being materialized into.
Definition Core.h:374
const SymbolFlagsMap & getSymbols() const
Returns the symbol flags map for this responsibility instance.
Definition Core.h:383
A materialization task.
Definition Core.h:1079
MaterializationTask(std::unique_ptr< MaterializationUnit > MU, std::unique_ptr< MaterializationResponsibility > MR)
Definition Core.h:1083
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group,...
const SymbolNameVector & getSymbols() const
Definition Core.h:304
std::shared_ptr< SymbolStringPool > getSymbolStringPool()
Definition Core.h:302
MissingSymbolDefinitions(std::shared_ptr< SymbolStringPool > SSP, std::string ModuleName, SymbolNameVector Symbols)
Definition Core.h:296
const std::string & getModuleName() const
Definition Core.h:303
Platforms set up standard symbols and mediate interactions between dynamic initializers (e....
Definition Core.h:1038
virtual Error teardownJITDylib(JITDylib &JD)=0
This method will be called outside the session lock each time a JITDylib is removed to allow the Plat...
static void lookupInitSymbolsAsync(unique_function< void(Error)> OnComplete, ExecutionSession &ES, const DenseMap< JITDylib *, SymbolLookupSet > &InitSyms)
Performs an async lookup for the given symbols in each of the given JITDylibs, calling the given hand...
Definition Core.cpp:1489
virtual Error notifyRemoving(ResourceTracker &RT)=0
This method will be called under the ExecutionSession lock when a ResourceTracker is removed.
static Expected< DenseMap< JITDylib *, SymbolMap > > lookupInitSymbols(ExecutionSession &ES, const DenseMap< JITDylib *, SymbolLookupSet > &InitSyms)
A utility function for looking up initializer symbols.
Definition Core.cpp:1440
virtual Error notifyAdding(ResourceTracker &RT, const MaterializationUnit &MU)=0
This method will be called under the ExecutionSession lock each time a MaterializationUnit is added t...
virtual Error setupJITDylib(JITDylib &JD)=0
This method will be called outside the session lock each time a JITDylib is created (unless it is cre...
ReExportsMaterializationUnit(JITDylib *SourceJD, JITDylibLookupFlags SourceJDLookupFlags, SymbolAliasMap Aliases)
SourceJD is allowed to be nullptr, in which case the source JITDylib is taken to be whatever JITDylib...
Definition Core.cpp:290
std::function< bool(SymbolStringPtr)> SymbolPredicate
Definition Core.h:1739
Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD, JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &LookupSet) override
DefinitionGenerators should override this method to insert new definitions into the parent JITDylib.
Definition Core.cpp:587
ReexportsGenerator(JITDylib &SourceJD, JITDylibLookupFlags SourceJDLookupFlags, SymbolPredicate Allow=SymbolPredicate())
Create a reexports generator.
Definition Core.cpp:581
Listens for ResourceTracker operations.
Definition Core.h:111
virtual Error handleRemoveResources(JITDylib &JD, ResourceKey K)=0
This function will be called outside the session lock.
virtual void handleTransferResources(JITDylib &JD, ResourceKey DstK, ResourceKey SrcK)=0
This function will be called inside the session lock.
ResourceTrackerDefunct(ResourceTrackerSP RT)
Definition Core.cpp:73
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition Core.cpp:80
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition Core.cpp:76
API to remove / transfer ownership of JIT resources.
Definition Core.h:63
JITDylib & getJITDylib() const
Return the JITDylib targeted by this tracker.
Definition Core.h:78
friend class JITDylib
Definition Core.h:66
ResourceTracker & operator=(const ResourceTracker &)=delete
ResourceKey getKeyUnsafe() const
Returns the key associated with this tracker.
Definition Core.h:100
LLVM_ABI void transferTo(ResourceTracker &DstRT)
Transfer all resources associated with this key to the given tracker, which must target the same JITD...
Definition Core.cpp:61
ResourceTracker & operator=(ResourceTracker &&)=delete
LLVM_ABI ~ResourceTracker()
Definition Core.cpp:52
ResourceTracker(const ResourceTracker &)=delete
friend class MaterializationResponsibility
Definition Core.h:67
bool isDefunct() const
Return true if this tracker has become defunct.
Definition Core.h:95
ResourceTracker(ResourceTracker &&)=delete
Error withResourceKeyDo(Func &&F)
Runs the given callback under the session lock, passing in the associated ResourceKey.
Definition Core.h:1617
friend class ExecutionSession
Definition Core.h:65
LLVM_ABI Error remove()
Remove all resources associated with this key.
Definition Core.cpp:57
A set of symbols to look up, each associated with a SymbolLookupFlags value.
Pointer to a pooled string representing a symbol name.
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition Core.cpp:165
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition Core.cpp:169
const SymbolNameSet & getSymbols() const
Definition Core.h:280
SymbolsCouldNotBeRemoved(std::shared_ptr< SymbolStringPool > SSP, SymbolNameSet Symbols)
Definition Core.cpp:159
std::shared_ptr< SymbolStringPool > getSymbolStringPool()
Definition Core.h:279
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition Core.cpp:155
SymbolsNotFound(std::shared_ptr< SymbolStringPool > SSP, SymbolNameSet Symbols)
Definition Core.cpp:138
const SymbolNameVector & getSymbols() const
Definition Core.h:262
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition Core.cpp:151
std::shared_ptr< SymbolStringPool > getSymbolStringPool()
Definition Core.h:261
UnexpectedSymbolDefinitions(std::shared_ptr< SymbolStringPool > SSP, std::string ModuleName, SymbolNameVector Symbols)
Definition Core.h:320
std::shared_ptr< SymbolStringPool > getSymbolStringPool()
Definition Core.h:326
const std::string & getModuleName() const
Definition Core.h:327
const SymbolNameVector & getSymbols() const
Definition Core.h:328
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition Core.cpp:131
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition Core.cpp:127
UnsatisfiedSymbolDependencies(std::shared_ptr< SymbolStringPool > SSP, JITDylibSP JD, SymbolNameSet FailedSymbols, SymbolDependenceMap BadDeps, std::string Explanation)
Definition Core.cpp:119
WaitingOnGraph class template.
C++ wrapper function buffer: Same as CWrapperFunctionBuffer but auto-releases memory.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
unique_function is a type-erasing functor similar to std::function.
JITDylibSearchOrder makeJITDylibSearchOrder(ArrayRef< JITDylib * > JDs, JITDylibLookupFlags Flags=JITDylibLookupFlags::MatchExportedSymbolsOnly)
Convenience function for creating a search order from an ArrayRef of JITDylib*, all with the same fla...
Definition Core.h:153
std::vector< std::pair< JITDylib *, JITDylibLookupFlags > > JITDylibSearchOrder
A list of (JITDylib*, JITDylibLookupFlags) pairs to be used as a search order during symbol lookup.
Definition Core.h:148
IntrusiveRefCntPtr< JITDylib > JITDylibSP
Definition Core.h:58
IntrusiveRefCntPtr< ResourceTracker > ResourceTrackerSP
Definition Core.h:57
std::unique_ptr< ReExportsMaterializationUnit > symbolAliases(SymbolAliasMap Aliases)
Create a ReExportsMaterializationUnit with the given aliases.
Definition Core.h:523
std::function< void(const SymbolDependenceMap &)> RegisterDependenciesFunction
Callback to register the dependencies for a given query.
Definition Core.h:179
uintptr_t ResourceKey
Definition Core.h:60
std::unique_ptr< ReExportsMaterializationUnit > reexports(JITDylib &SourceJD, SymbolAliasMap Aliases, JITDylibLookupFlags SourceJDLookupFlags=JITDylibLookupFlags::MatchExportedSymbolsOnly)
Create a materialization unit for re-exporting symbols from another JITDylib with alternative names/f...
Definition Core.h:532
JITDylibLookupFlags
Lookup flags that apply to each dylib in the search order for a lookup.
Definition Core.h:132
detail::WaitingOnGraph< JITDylib *, NonOwningSymbolStringPtr > WaitingOnGraph
Definition Core.h:54
DenseMap< SymbolStringPtr, ExecutorSymbolDef > SymbolMap
A map from symbol names (as SymbolStringPtrs) to JITSymbols (address/flags pairs).
static std::unique_ptr< UnwindInfoManager > Instance
LookupKind
Describes the kind of lookup being performed.
Definition Core.h:144
LLVM_ABI RegisterDependenciesFunction NoDependenciesToRegister
This can be used as the value for a RegisterDependenciesFunction if there are no dependants to regist...
Definition Core.cpp:40
std::vector< SymbolStringPtr > SymbolNameVector
A vector of symbol names.
DenseMap< JITDylib *, SymbolNameSet > SymbolDependenceMap
A map from JITDylibs to sets of symbols.
DenseSet< SymbolStringPtr > SymbolNameSet
A set of symbol names (represented by SymbolStringPtrs for.
SymbolState
Represents the state that a symbol has reached during materialization.
Definition Core.h:545
@ Materializing
Added to the symbol table, never queried.
Definition Core.h:548
@ NeverSearched
No symbol should be in this state.
Definition Core.h:547
@ Ready
Emitted to memory, but waiting on transitive dependencies.
Definition Core.h:551
@ Emitted
Assigned address, still materializing.
Definition Core.h:550
@ Resolved
Queried, materialization begun.
Definition Core.h:549
DenseMap< SymbolStringPtr, SymbolAliasMapEntry > SymbolAliasMap
A map of Symbols to (Symbol, Flags) pairs.
Definition Core.h:173
unique_function< void(Expected< SymbolMap >)> SymbolsResolvedCallback
Callback to notify client that symbols have been resolved.
Definition Core.h:176
LLVM_ABI Expected< SymbolAliasMap > buildSimpleReexportsAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols)
Build a SymbolAliasMap for the common case where you want to re-export symbols from another JITDylib ...
Definition Core.cpp:482
DenseMap< SymbolStringPtr, JITSymbolFlags > SymbolFlagsMap
A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
Definition Error.cpp:61
testing::Matcher< const detail::ErrorHolder & > Failed()
Definition Error.h:198
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
ArrayRef(const T &OneElt) -> ArrayRef< T >
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:1917
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
JITSymbolFlags AliasFlags
Definition Core.h:169
SymbolAliasMapEntry(SymbolStringPtr Aliasee, JITSymbolFlags AliasFlags)
Definition Core.h:165
SymbolStringPtr Aliasee
Definition Core.h:168
A set of symbols and the their dependencies.
Definition Core.h:337
SymbolDependenceMap Dependencies
Definition Core.h:339