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