forked from OSchip/llvm-project
[ORC] Rename VSO to JITDylib.
VSO was a little close to VDSO (an acronym on Linux for Virtual Dynamic Shared Object) for comfort. It also risks giving the impression that instances of this class could be shared between ExecutionSessions, which they can not. JITDylib seems moderately less confusing, while still hinting at how this class is intended to be used, i.e. as a JIT-compiled stand-in for a dynamic library (code that would have been a dynamic library if you had wanted to compile it ahead of time). llvm-svn: 340084
This commit is contained in:
parent
469f076356
commit
d5f56c5979
|
@ -75,16 +75,16 @@ public:
|
|||
IndirectStubsManagerBuilder BuildIndirectStubsManager,
|
||||
GetAvailableContextFunction GetAvailableContext);
|
||||
|
||||
Error add(VSO &V, VModuleKey K, std::unique_ptr<Module> M) override;
|
||||
Error add(JITDylib &V, VModuleKey K, std::unique_ptr<Module> M) override;
|
||||
|
||||
void emit(MaterializationResponsibility R, VModuleKey K,
|
||||
std::unique_ptr<Module> M) override;
|
||||
|
||||
private:
|
||||
using StubManagersMap =
|
||||
std::map<const VSO *, std::unique_ptr<IndirectStubsManager>>;
|
||||
std::map<const JITDylib *, std::unique_ptr<IndirectStubsManager>>;
|
||||
|
||||
IndirectStubsManager &getStubsManager(const VSO &V);
|
||||
IndirectStubsManager &getStubsManager(const JITDylib &JD);
|
||||
|
||||
void emitExtractedFunctionsModule(MaterializationResponsibility R,
|
||||
std::unique_ptr<Module> M);
|
||||
|
|
|
@ -33,7 +33,7 @@ class AsynchronousSymbolQuery;
|
|||
class ExecutionSession;
|
||||
class MaterializationUnit;
|
||||
class MaterializationResponsibility;
|
||||
class VSO;
|
||||
class JITDylib;
|
||||
|
||||
/// VModuleKey provides a unique identifier (allocated and managed by
|
||||
/// ExecutionSessions) for a module added to the JIT.
|
||||
|
@ -61,16 +61,16 @@ raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap &Symbols);
|
|||
|
||||
/// A base class for materialization failures that allows the failing
|
||||
/// symbols to be obtained for logging.
|
||||
using SymbolDependenceMap = std::map<VSO *, SymbolNameSet>;
|
||||
using SymbolDependenceMap = std::map<JITDylib *, SymbolNameSet>;
|
||||
|
||||
/// Render a SymbolDependendeMap.
|
||||
raw_ostream &operator<<(raw_ostream &OS, const SymbolDependenceMap &Deps);
|
||||
|
||||
/// A list of VSO pointers.
|
||||
using VSOList = std::vector<VSO *>;
|
||||
/// A list of JITDylib pointers.
|
||||
using JITDylibList = std::vector<JITDylib *>;
|
||||
|
||||
/// Render a VSOList.
|
||||
raw_ostream &operator<<(raw_ostream &OS, const VSOList &VSOs);
|
||||
/// Render a JITDylibList.
|
||||
raw_ostream &operator<<(raw_ostream &OS, const JITDylibList &JDs);
|
||||
|
||||
/// Callback to notify client that symbols have been resolved.
|
||||
using SymbolsResolvedCallback = std::function<void(Expected<SymbolMap>)>;
|
||||
|
@ -86,7 +86,8 @@ using RegisterDependenciesFunction =
|
|||
/// are no dependants to register with.
|
||||
extern RegisterDependenciesFunction NoDependenciesToRegister;
|
||||
|
||||
/// Used to notify a VSO that the given set of symbols failed to materialize.
|
||||
/// Used to notify a JITDylib that the given set of symbols failed to
|
||||
/// materialize.
|
||||
class FailedToMaterialize : public ErrorInfo<FailedToMaterialize> {
|
||||
public:
|
||||
static char ID;
|
||||
|
@ -115,7 +116,7 @@ private:
|
|||
};
|
||||
|
||||
/// Tracks responsibility for materialization, and mediates interactions between
|
||||
/// MaterializationUnits and VSOs.
|
||||
/// MaterializationUnits and JDs.
|
||||
///
|
||||
/// An instance of this class is passed to MaterializationUnits when their
|
||||
/// materialize method is called. It allows MaterializationUnits to resolve and
|
||||
|
@ -133,9 +134,9 @@ public:
|
|||
/// finalized or notified of an error.
|
||||
~MaterializationResponsibility();
|
||||
|
||||
/// Returns the target VSO that these symbols are being materialized
|
||||
/// Returns the target JITDylib that these symbols are being materialized
|
||||
/// into.
|
||||
VSO &getTargetVSO() const { return V; }
|
||||
JITDylib &getTargetJITDylib() const { return JD; }
|
||||
|
||||
/// Returns the symbol flags map for this responsibility instance.
|
||||
SymbolFlagsMap getSymbols() { return SymbolFlags; }
|
||||
|
@ -143,7 +144,7 @@ public:
|
|||
/// Returns the names of any symbols covered by this
|
||||
/// MaterializationResponsibility object that have queries pending. This
|
||||
/// information can be used to return responsibility for unrequested symbols
|
||||
/// back to the VSO via the delegate method.
|
||||
/// back to the JITDylib via the delegate method.
|
||||
SymbolNameSet getRequestedSymbols();
|
||||
|
||||
/// Resolves the given symbols. Individual calls to this method may
|
||||
|
@ -154,8 +155,8 @@ public:
|
|||
/// Finalizes all symbols tracked by this instance.
|
||||
void finalize();
|
||||
|
||||
/// Adds new symbols to the VSO and this responsibility instance.
|
||||
/// VSO entries start out in the materializing state.
|
||||
/// Adds new symbols to the JITDylib and this responsibility instance.
|
||||
/// JITDylib entries start out in the materializing state.
|
||||
///
|
||||
/// This method can be used by materialization units that want to add
|
||||
/// additional symbols at materialization time (e.g. stubs, compile
|
||||
|
@ -186,11 +187,11 @@ public:
|
|||
void addDependenciesForAll(const SymbolDependenceMap &Dependencies);
|
||||
|
||||
private:
|
||||
/// Create a MaterializationResponsibility for the given VSO and
|
||||
/// Create a MaterializationResponsibility for the given JITDylib and
|
||||
/// initial symbols.
|
||||
MaterializationResponsibility(VSO &V, SymbolFlagsMap SymbolFlags);
|
||||
MaterializationResponsibility(JITDylib &JD, SymbolFlagsMap SymbolFlags);
|
||||
|
||||
VSO &V;
|
||||
JITDylib &JD;
|
||||
SymbolFlagsMap SymbolFlags;
|
||||
};
|
||||
|
||||
|
@ -199,9 +200,9 @@ private:
|
|||
/// overriding definitions are encountered).
|
||||
///
|
||||
/// MaterializationUnits are used when providing lazy definitions of symbols to
|
||||
/// VSOs. The VSO will call materialize when the address of a symbol is
|
||||
/// requested via the lookup method. The VSO will call discard if a stronger
|
||||
/// definition is added or already present.
|
||||
/// JITDylibs. The JITDylib will call materialize when the address of a symbol
|
||||
/// is requested via the lookup method. The JITDylib will call discard if a
|
||||
/// stronger definition is added or already present.
|
||||
class MaterializationUnit {
|
||||
public:
|
||||
MaterializationUnit(SymbolFlagsMap InitalSymbolFlags)
|
||||
|
@ -215,15 +216,15 @@ public:
|
|||
/// Called by materialization dispatchers (see
|
||||
/// ExecutionSession::DispatchMaterializationFunction) to trigger
|
||||
/// materialization of this MaterializationUnit.
|
||||
void doMaterialize(VSO &V) {
|
||||
materialize(MaterializationResponsibility(V, std::move(SymbolFlags)));
|
||||
void doMaterialize(JITDylib &JD) {
|
||||
materialize(MaterializationResponsibility(JD, std::move(SymbolFlags)));
|
||||
}
|
||||
|
||||
/// Called by VSOs to notify MaterializationUnits that the given symbol has
|
||||
/// been overridden.
|
||||
void doDiscard(const VSO &V, SymbolStringPtr Name) {
|
||||
/// Called by JITDylibs to notify MaterializationUnits that the given symbol
|
||||
/// has been overridden.
|
||||
void doDiscard(const JITDylib &JD, SymbolStringPtr Name) {
|
||||
SymbolFlags.erase(Name);
|
||||
discard(V, std::move(Name));
|
||||
discard(JD, std::move(Name));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -241,7 +242,7 @@ private:
|
|||
/// from the source (e.g. if the source is an LLVM IR Module and the
|
||||
/// symbol is a function, delete the function body or mark it available
|
||||
/// externally).
|
||||
virtual void discard(const VSO &V, SymbolStringPtr Name) = 0;
|
||||
virtual void discard(const JITDylib &JD, SymbolStringPtr Name) = 0;
|
||||
};
|
||||
|
||||
using MaterializationUnitList =
|
||||
|
@ -257,19 +258,19 @@ public:
|
|||
|
||||
private:
|
||||
void materialize(MaterializationResponsibility R) override;
|
||||
void discard(const VSO &V, SymbolStringPtr Name) override;
|
||||
void discard(const JITDylib &JD, SymbolStringPtr Name) override;
|
||||
static SymbolFlagsMap extractFlags(const SymbolMap &Symbols);
|
||||
|
||||
SymbolMap Symbols;
|
||||
};
|
||||
|
||||
/// Create an AbsoluteSymbolsMaterializationUnit with the given symbols.
|
||||
/// Useful for inserting absolute symbols into a VSO. E.g.:
|
||||
/// Useful for inserting absolute symbols into a JITDylib. E.g.:
|
||||
/// \code{.cpp}
|
||||
/// VSO &V = ...;
|
||||
/// JITDylib &JD = ...;
|
||||
/// SymbolStringPtr Foo = ...;
|
||||
/// JITEvaluatedSymbol FooSym = ...;
|
||||
/// if (auto Err = V.define(absoluteSymbols({{Foo, FooSym}})))
|
||||
/// if (auto Err = JD.define(absoluteSymbols({{Foo, FooSym}})))
|
||||
/// return Err;
|
||||
/// \endcode
|
||||
///
|
||||
|
@ -295,32 +296,31 @@ using SymbolAliasMap = std::map<SymbolStringPtr, SymbolAliasMapEntry>;
|
|||
/// aliased with alternate flags.
|
||||
class ReExportsMaterializationUnit : public MaterializationUnit {
|
||||
public:
|
||||
/// SourceVSO is allowed to be nullptr, in which case the source VSO is
|
||||
/// taken to be whatever VSO these definitions are materialized in. This
|
||||
/// is useful for defining aliases within a VSO.
|
||||
/// SourceJD is allowed to be nullptr, in which case the source JITDylib is
|
||||
/// taken to be whatever JITDylib these definitions are materialized in. This
|
||||
/// is useful for defining aliases within a JITDylib.
|
||||
///
|
||||
/// Note: Care must be taken that no sets of aliases form a cycle, as such
|
||||
/// a cycle will result in a deadlock when any symbol in the cycle is
|
||||
/// resolved.
|
||||
ReExportsMaterializationUnit(VSO *SourceVSO, SymbolAliasMap Aliases);
|
||||
ReExportsMaterializationUnit(JITDylib *SourceJD, SymbolAliasMap Aliases);
|
||||
|
||||
private:
|
||||
void materialize(MaterializationResponsibility R) override;
|
||||
void discard(const VSO &V, SymbolStringPtr Name) override;
|
||||
void discard(const JITDylib &JD, SymbolStringPtr Name) override;
|
||||
static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases);
|
||||
|
||||
VSO *SourceVSO = nullptr;
|
||||
JITDylib *SourceJD = nullptr;
|
||||
SymbolAliasMap Aliases;
|
||||
};
|
||||
|
||||
/// Create a ReExportsMaterializationUnit with the given aliases.
|
||||
/// Useful for defining symbol aliases.: E.g., given a VSO V containing symbols
|
||||
/// "foo" and "bar", we can define aliases "baz" (for "foo") and "qux" (for
|
||||
/// "bar") with:
|
||||
/// \code{.cpp}
|
||||
/// Useful for defining symbol aliases.: E.g., given a JITDylib JD containing
|
||||
/// symbols "foo" and "bar", we can define aliases "baz" (for "foo") and "qux"
|
||||
/// (for "bar") with: \code{.cpp}
|
||||
/// SymbolStringPtr Baz = ...;
|
||||
/// SymbolStringPtr Qux = ...;
|
||||
/// if (auto Err = V.define(symbolAliases({
|
||||
/// if (auto Err = JD.define(symbolAliases({
|
||||
/// {Baz, { Foo, JITSymbolFlags::Exported }},
|
||||
/// {Qux, { Bar, JITSymbolFlags::Weak }}}))
|
||||
/// return Err;
|
||||
|
@ -331,42 +331,43 @@ symbolAliases(SymbolAliasMap Aliases) {
|
|||
std::move(Aliases));
|
||||
}
|
||||
|
||||
/// Create a materialization unit for re-exporting symbols from another VSO
|
||||
/// Create a materialization unit for re-exporting symbols from another JITDylib
|
||||
/// with alternative names/flags.
|
||||
inline std::unique_ptr<ReExportsMaterializationUnit>
|
||||
reexports(VSO &SourceV, SymbolAliasMap Aliases) {
|
||||
return llvm::make_unique<ReExportsMaterializationUnit>(&SourceV,
|
||||
reexports(JITDylib &SourceJD, SymbolAliasMap Aliases) {
|
||||
return llvm::make_unique<ReExportsMaterializationUnit>(&SourceJD,
|
||||
std::move(Aliases));
|
||||
}
|
||||
|
||||
/// Build a SymbolAliasMap for the common case where you want to re-export
|
||||
/// symbols from another VSO with the same linkage/flags.
|
||||
/// symbols from another JITDylib with the same linkage/flags.
|
||||
Expected<SymbolAliasMap>
|
||||
buildSimpleReexportsAliasMap(VSO &SourceV, const SymbolNameSet &Symbols);
|
||||
buildSimpleReexportsAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols);
|
||||
|
||||
class ReexportsFallbackDefinitionGenerator {
|
||||
public:
|
||||
using SymbolPredicate = std::function<bool(SymbolStringPtr)>;
|
||||
ReexportsFallbackDefinitionGenerator(VSO &BackingVSO, SymbolPredicate Allow);
|
||||
SymbolNameSet operator()(VSO &V, const SymbolNameSet &Names);
|
||||
ReexportsFallbackDefinitionGenerator(JITDylib &BackingJD,
|
||||
SymbolPredicate Allow);
|
||||
SymbolNameSet operator()(JITDylib &JD, const SymbolNameSet &Names);
|
||||
|
||||
private:
|
||||
VSO &BackingVSO;
|
||||
JITDylib &BackingJD;
|
||||
SymbolPredicate Allow;
|
||||
};
|
||||
|
||||
/// Base utilities for ExecutionSession.
|
||||
class ExecutionSessionBase {
|
||||
// FIXME: Remove this when we remove the old ORC layers.
|
||||
friend class VSO;
|
||||
friend class JITDylib;
|
||||
|
||||
public:
|
||||
/// For reporting errors.
|
||||
using ErrorReporter = std::function<void(Error)>;
|
||||
|
||||
/// For dispatching MaterializationUnit::materialize calls.
|
||||
using DispatchMaterializationFunction =
|
||||
std::function<void(VSO &V, std::unique_ptr<MaterializationUnit> MU)>;
|
||||
using DispatchMaterializationFunction = std::function<void(
|
||||
JITDylib &JD, std::unique_ptr<MaterializationUnit> MU)>;
|
||||
|
||||
/// Construct an ExecutionSessionBase.
|
||||
///
|
||||
|
@ -422,7 +423,7 @@ public:
|
|||
SymbolNameSet Names, bool WaiUntilReady,
|
||||
RegisterDependenciesFunction RegisterDependencies);
|
||||
|
||||
/// Search the given VSO list for the given symbols.
|
||||
/// Search the given JITDylib list for the given symbols.
|
||||
///
|
||||
///
|
||||
/// The OnResolve callback will be called once all requested symbols are
|
||||
|
@ -440,7 +441,7 @@ public:
|
|||
/// dependenant symbols for this query (e.g. it is being made by a top level
|
||||
/// client to get an address to call) then the value NoDependenciesToRegister
|
||||
/// can be used.
|
||||
void lookup(const VSOList &VSOs, const SymbolNameSet &Symbols,
|
||||
void lookup(const JITDylibList &JDs, const SymbolNameSet &Symbols,
|
||||
SymbolsResolvedCallback OnResolve, SymbolsReadyCallback OnReady,
|
||||
RegisterDependenciesFunction RegisterDependencies);
|
||||
|
||||
|
@ -451,14 +452,15 @@ public:
|
|||
/// or an error occurs. If WaitUntilReady is false and an error occurs
|
||||
/// after resolution, the function will return a success value, but the
|
||||
/// error will be reported via reportErrors.
|
||||
Expected<SymbolMap> lookup(const VSOList &VSOs, const SymbolNameSet &Symbols,
|
||||
Expected<SymbolMap> lookup(const JITDylibList &JDs,
|
||||
const SymbolNameSet &Symbols,
|
||||
RegisterDependenciesFunction RegisterDependencies,
|
||||
bool WaitUntilReady = true);
|
||||
|
||||
/// Materialize the given unit.
|
||||
void dispatchMaterialization(VSO &V,
|
||||
void dispatchMaterialization(JITDylib &JD,
|
||||
std::unique_ptr<MaterializationUnit> MU) {
|
||||
DispatchMaterialization(V, std::move(MU));
|
||||
DispatchMaterialization(JD, std::move(MU));
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -467,8 +469,9 @@ private:
|
|||
}
|
||||
|
||||
static void
|
||||
materializeOnCurrentThread(VSO &V, std::unique_ptr<MaterializationUnit> MU) {
|
||||
MU->doMaterialize(V);
|
||||
materializeOnCurrentThread(JITDylib &JD,
|
||||
std::unique_ptr<MaterializationUnit> MU) {
|
||||
MU->doMaterialize(JD);
|
||||
}
|
||||
|
||||
void runOutstandingMUs();
|
||||
|
@ -483,7 +486,7 @@ private:
|
|||
// FIXME: Remove this (and runOutstandingMUs) once the linking layer works
|
||||
// with callbacks from asynchronous queries.
|
||||
mutable std::recursive_mutex OutstandingMUsMutex;
|
||||
std::vector<std::pair<VSO *, std::unique_ptr<MaterializationUnit>>>
|
||||
std::vector<std::pair<JITDylib *, std::unique_ptr<MaterializationUnit>>>
|
||||
OutstandingMUs;
|
||||
};
|
||||
|
||||
|
@ -493,7 +496,7 @@ private:
|
|||
/// makes a callback when all symbols are available.
|
||||
class AsynchronousSymbolQuery {
|
||||
friend class ExecutionSessionBase;
|
||||
friend class VSO;
|
||||
friend class JITDylib;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -528,9 +531,9 @@ public:
|
|||
void handleFullyReady();
|
||||
|
||||
private:
|
||||
void addQueryDependence(VSO &V, SymbolStringPtr Name);
|
||||
void addQueryDependence(JITDylib &JD, SymbolStringPtr Name);
|
||||
|
||||
void removeQueryDependence(VSO &V, const SymbolStringPtr &Name);
|
||||
void removeQueryDependence(JITDylib &JD, const SymbolStringPtr &Name);
|
||||
|
||||
bool canStillFail();
|
||||
|
||||
|
@ -550,79 +553,82 @@ private:
|
|||
///
|
||||
/// Represents a virtual shared object. Instances can not be copied or moved, so
|
||||
/// their addresses may be used as keys for resource management.
|
||||
/// VSO state changes must be made via an ExecutionSession to guarantee that
|
||||
/// they are synchronized with respect to other VSO operations.
|
||||
class VSO {
|
||||
/// JITDylib state changes must be made via an ExecutionSession to guarantee
|
||||
/// that they are synchronized with respect to other JITDylib operations.
|
||||
class JITDylib {
|
||||
friend class AsynchronousSymbolQuery;
|
||||
friend class ExecutionSession;
|
||||
friend class ExecutionSessionBase;
|
||||
friend class MaterializationResponsibility;
|
||||
public:
|
||||
using FallbackDefinitionGeneratorFunction =
|
||||
std::function<SymbolNameSet(VSO &Parent, const SymbolNameSet &Names)>;
|
||||
using FallbackDefinitionGeneratorFunction = std::function<SymbolNameSet(
|
||||
JITDylib &Parent, const SymbolNameSet &Names)>;
|
||||
|
||||
using AsynchronousSymbolQuerySet =
|
||||
std::set<std::shared_ptr<AsynchronousSymbolQuery>>;
|
||||
|
||||
VSO(const VSO &) = delete;
|
||||
VSO &operator=(const VSO &) = delete;
|
||||
VSO(VSO &&) = delete;
|
||||
VSO &operator=(VSO &&) = delete;
|
||||
JITDylib(const JITDylib &) = delete;
|
||||
JITDylib &operator=(const JITDylib &) = delete;
|
||||
JITDylib(JITDylib &&) = delete;
|
||||
JITDylib &operator=(JITDylib &&) = delete;
|
||||
|
||||
/// Get the name for this VSO.
|
||||
const std::string &getName() const { return VSOName; }
|
||||
/// Get the name for this JITDylib.
|
||||
const std::string &getName() const { return JITDylibName; }
|
||||
|
||||
/// Get a reference to the ExecutionSession for this VSO.
|
||||
/// Get a reference to the ExecutionSession for this JITDylib.
|
||||
ExecutionSessionBase &getExecutionSession() const { return ES; }
|
||||
|
||||
/// Set a fallback defenition generator. If set, lookup and lookupFlags will
|
||||
/// pass the unresolved symbols set to the fallback definition generator,
|
||||
/// allowing it to add a new definition to the VSO.
|
||||
/// allowing it to add a new definition to the JITDylib.
|
||||
void setFallbackDefinitionGenerator(
|
||||
FallbackDefinitionGeneratorFunction FallbackDefinitionGenerator) {
|
||||
this->FallbackDefinitionGenerator = std::move(FallbackDefinitionGenerator);
|
||||
}
|
||||
|
||||
/// Set the search order to be used when fixing up definitions in VSO.
|
||||
/// Set the search order to be used when fixing up definitions in JITDylib.
|
||||
/// This will replace the previous search order, and apply to any symbol
|
||||
/// resolutions made for definitions in this VSO after the call to
|
||||
/// resolutions made for definitions in this JITDylib after the call to
|
||||
/// setSearchOrder (even if the definition itself was added before the
|
||||
/// call).
|
||||
///
|
||||
/// If SearchThisVSOFirst is set, which by default it is, then this VSO will
|
||||
/// add itself to the beginning of the SearchOrder (Clients should *not*
|
||||
/// put this VSO in the list in this case, to avoid redundant lookups).
|
||||
/// If SearchThisJITDylibFirst is set, which by default it is, then this
|
||||
/// JITDylib will add itself to the beginning of the SearchOrder (Clients
|
||||
/// should *not* put this JITDylib in the list in this case, to avoid
|
||||
/// redundant lookups).
|
||||
///
|
||||
/// If SearchThisVSOFirst is false then the search order will be used as
|
||||
/// If SearchThisJITDylibFirst is false then the search order will be used as
|
||||
/// given. The main motivation for this feature is to support deliberate
|
||||
/// shadowing of symbols in this VSO by a facade VSO. For example, the
|
||||
/// facade may resolve function names to stubs, and the stubs may compile
|
||||
/// shadowing of symbols in this JITDylib by a facade JITDylib. For example,
|
||||
/// the facade may resolve function names to stubs, and the stubs may compile
|
||||
/// lazily by looking up symbols in this dylib. Adding the facade dylib
|
||||
/// as the first in the search order (instead of this dylib) ensures that
|
||||
/// definitions within this dylib resolve to the lazy-compiling stubs,
|
||||
/// rather than immediately materializing the definitions in this dylib.
|
||||
void setSearchOrder(VSOList NewSearchOrder, bool SearchThisVSOFirst = true);
|
||||
void setSearchOrder(JITDylibList NewSearchOrder,
|
||||
bool SearchThisJITDylibFirst = true);
|
||||
|
||||
/// Add the given VSO to the search order for definitions in this VSO.
|
||||
void addToSearchOrder(VSO &V);
|
||||
/// Add the given JITDylib to the search order for definitions in this
|
||||
/// JITDylib.
|
||||
void addToSearchOrder(JITDylib &JD);
|
||||
|
||||
/// Replace OldV with NewV in the search order if OldV is present. Otherwise
|
||||
/// this operation is a no-op.
|
||||
void replaceInSearchOrder(VSO &OldV, VSO &NewV);
|
||||
/// Replace OldJD with NewJD in the search order if OldJD is present.
|
||||
/// Otherwise this operation is a no-op.
|
||||
void replaceInSearchOrder(JITDylib &OldJD, JITDylib &NewJD);
|
||||
|
||||
/// Remove the given VSO from the search order for this VSO if it is
|
||||
/// Remove the given JITDylib from the search order for this JITDylib if it is
|
||||
/// present. Otherwise this operation is a no-op.
|
||||
void removeFromSearchOrder(VSO &V);
|
||||
void removeFromSearchOrder(JITDylib &JD);
|
||||
|
||||
/// Do something with the search order (run under the session lock).
|
||||
template <typename Func>
|
||||
auto withSearchOrderDo(Func &&F)
|
||||
-> decltype(F(std::declval<const VSOList &>())) {
|
||||
-> decltype(F(std::declval<const JITDylibList &>())) {
|
||||
return ES.runSessionLocked([&]() { return F(SearchOrder); });
|
||||
}
|
||||
|
||||
/// Define all symbols provided by the materialization unit to be part
|
||||
/// of the given VSO.
|
||||
/// of the given JITDylib.
|
||||
template <typename UniquePtrToMaterializationUnit>
|
||||
typename std::enable_if<
|
||||
std::is_convertible<
|
||||
|
@ -645,15 +651,15 @@ public:
|
|||
});
|
||||
}
|
||||
|
||||
/// Search the given VSO for the symbols in Symbols. If found, store
|
||||
/// Search the given JITDylib for the symbols in Symbols. If found, store
|
||||
/// the flags for each symbol in Flags. Returns any unresolved symbols.
|
||||
SymbolFlagsMap lookupFlags(const SymbolNameSet &Names);
|
||||
|
||||
/// Dump current VSO state to OS.
|
||||
/// Dump current JITDylib state to OS.
|
||||
void dump(raw_ostream &OS);
|
||||
|
||||
/// FIXME: Remove this when we remove the old ORC layers.
|
||||
/// Search the given VSOs in order for the symbols in Symbols. Results
|
||||
/// Search the given JITDylibs in order for the symbols in Symbols. Results
|
||||
/// (once they become available) will be returned via the given Query.
|
||||
///
|
||||
/// If any symbol is not found then the unresolved symbols will be returned,
|
||||
|
@ -693,7 +699,7 @@ private:
|
|||
LLVM_MARK_AS_BITMASK_ENUM(NotifyFullyReady)
|
||||
};
|
||||
|
||||
VSO(ExecutionSessionBase &ES, std::string Name);
|
||||
JITDylib(ExecutionSessionBase &ES, std::string Name);
|
||||
|
||||
Error defineImpl(MaterializationUnit &MU);
|
||||
|
||||
|
@ -734,12 +740,12 @@ private:
|
|||
void notifyFailed(const SymbolNameSet &FailedSymbols);
|
||||
|
||||
ExecutionSessionBase &ES;
|
||||
std::string VSOName;
|
||||
std::string JITDylibName;
|
||||
SymbolMap Symbols;
|
||||
UnmaterializedInfosMap UnmaterializedInfos;
|
||||
MaterializingInfosMap MaterializingInfos;
|
||||
FallbackDefinitionGeneratorFunction FallbackDefinitionGenerator;
|
||||
VSOList SearchOrder;
|
||||
JITDylibList SearchOrder;
|
||||
};
|
||||
|
||||
/// An ExecutionSession represents a running JIT program.
|
||||
|
@ -747,8 +753,8 @@ class ExecutionSession : public ExecutionSessionBase {
|
|||
public:
|
||||
using ErrorReporter = std::function<void(Error)>;
|
||||
|
||||
using DispatchMaterializationFunction =
|
||||
std::function<void(VSO &V, std::unique_ptr<MaterializationUnit> MU)>;
|
||||
using DispatchMaterializationFunction = std::function<void(
|
||||
JITDylib &JD, std::unique_ptr<MaterializationUnit> MU)>;
|
||||
|
||||
/// Construct an ExecutionEngine.
|
||||
///
|
||||
|
@ -756,21 +762,22 @@ public:
|
|||
ExecutionSession(std::shared_ptr<SymbolStringPool> SSP = nullptr)
|
||||
: ExecutionSessionBase(std::move(SSP)) {}
|
||||
|
||||
/// Add a new VSO to this ExecutionSession.
|
||||
VSO &createVSO(std::string Name);
|
||||
/// Add a new JITDylib to this ExecutionSession.
|
||||
JITDylib &createJITDylib(std::string Name);
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<VSO>> VSOs;
|
||||
std::vector<std::unique_ptr<JITDylib>> JDs;
|
||||
};
|
||||
|
||||
/// Look up the given names in the given VSOs.
|
||||
/// VSOs will be searched in order and no VSO pointer may be null.
|
||||
/// All symbols must be found within the given VSOs or an error
|
||||
/// Look up the given names in the given JITDylibs.
|
||||
/// JDs will be searched in order and no JITDylib pointer may be null.
|
||||
/// All symbols must be found within the given JITDylibs or an error
|
||||
/// will be returned.
|
||||
Expected<SymbolMap> lookup(const VSOList &VSOs, SymbolNameSet Names);
|
||||
Expected<SymbolMap> lookup(const JITDylibList &JDs, SymbolNameSet Names);
|
||||
|
||||
/// Look up a symbol by searching a list of VSOs.
|
||||
Expected<JITEvaluatedSymbol> lookup(const VSOList &VSOs, SymbolStringPtr Name);
|
||||
/// Look up a symbol by searching a list of JITDylibs.
|
||||
Expected<JITEvaluatedSymbol> lookup(const JITDylibList &JDs,
|
||||
SymbolStringPtr Name);
|
||||
|
||||
/// Mangles symbol names then uniques them in the context of an
|
||||
/// ExecutionSession.
|
||||
|
|
|
@ -171,7 +171,7 @@ private:
|
|||
|
||||
class CtorDtorRunner2 {
|
||||
public:
|
||||
CtorDtorRunner2(VSO &V) : V(V) {}
|
||||
CtorDtorRunner2(JITDylib &JD) : JD(JD) {}
|
||||
void add(iterator_range<CtorDtorIterator> CtorDtors);
|
||||
Error run();
|
||||
|
||||
|
@ -179,7 +179,7 @@ private:
|
|||
using CtorDtorList = std::vector<SymbolStringPtr>;
|
||||
using CtorDtorPriorityMap = std::map<unsigned, CtorDtorList>;
|
||||
|
||||
VSO &V;
|
||||
JITDylib &JD;
|
||||
CtorDtorPriorityMap CtorDtorsByPriority;
|
||||
};
|
||||
|
||||
|
@ -244,20 +244,20 @@ private:
|
|||
|
||||
class LocalCXXRuntimeOverrides2 : public LocalCXXRuntimeOverridesBase {
|
||||
public:
|
||||
Error enable(VSO &V, MangleAndInterner &Mangler);
|
||||
Error enable(JITDylib &JD, MangleAndInterner &Mangler);
|
||||
};
|
||||
|
||||
/// A utility class to expose symbols found via dlsym to the JIT.
|
||||
///
|
||||
/// If an instance of this class is attached to a VSO as a fallback definition
|
||||
/// generator, then any symbol found in the given DynamicLibrary that passes
|
||||
/// the 'Allow' predicate will be added to the VSO.
|
||||
/// If an instance of this class is attached to a JITDylib as a fallback
|
||||
/// definition generator, then any symbol found in the given DynamicLibrary that
|
||||
/// passes the 'Allow' predicate will be added to the JITDylib.
|
||||
class DynamicLibraryFallbackGenerator {
|
||||
public:
|
||||
using SymbolPredicate = std::function<bool(SymbolStringPtr)>;
|
||||
DynamicLibraryFallbackGenerator(sys::DynamicLibrary Dylib,
|
||||
const DataLayout &DL, SymbolPredicate Allow);
|
||||
SymbolNameSet operator()(VSO &V, const SymbolNameSet &Names);
|
||||
SymbolNameSet operator()(JITDylib &JD, const SymbolNameSet &Names);
|
||||
|
||||
private:
|
||||
sys::DynamicLibrary Dylib;
|
||||
|
|
|
@ -57,7 +57,7 @@ public:
|
|||
/// process to be used if a compile callback fails.
|
||||
JITCompileCallbackManager(ExecutionSession &ES,
|
||||
JITTargetAddress ErrorHandlerAddress)
|
||||
: ES(ES), CallbacksVSO(ES.createVSO("<Callbacks>")),
|
||||
: ES(ES), CallbacksJD(ES.createJITDylib("<Callbacks>")),
|
||||
ErrorHandlerAddress(ErrorHandlerAddress) {}
|
||||
|
||||
virtual ~JITCompileCallbackManager() = default;
|
||||
|
@ -91,7 +91,7 @@ private:
|
|||
|
||||
std::mutex CCMgrMutex;
|
||||
ExecutionSession &ES;
|
||||
VSO &CallbacksVSO;
|
||||
JITDylib &CallbacksJD;
|
||||
JITTargetAddress ErrorHandlerAddress;
|
||||
std::map<JITTargetAddress, SymbolStringPtr> AddrToSymbol;
|
||||
size_t NextCallbackId = 0;
|
||||
|
|
|
@ -37,36 +37,38 @@ public:
|
|||
/// Returns a reference to the ExecutionSession for this JIT instance.
|
||||
ExecutionSession &getExecutionSession() { return *ES; }
|
||||
|
||||
/// Returns a reference to the VSO representing the JIT'd main program.
|
||||
VSO &getMainVSO() { return Main; }
|
||||
/// Returns a reference to the JITDylib representing the JIT'd main program.
|
||||
JITDylib &getMainJITDylib() { return Main; }
|
||||
|
||||
/// Convenience method for defining an absolute symbol.
|
||||
Error defineAbsolute(StringRef Name, JITEvaluatedSymbol Address);
|
||||
|
||||
/// Adds an IR module to the given VSO.
|
||||
Error addIRModule(VSO &V, std::unique_ptr<Module> M);
|
||||
/// Adds an IR module to the given JITDylib.
|
||||
Error addIRModule(JITDylib &JD, std::unique_ptr<Module> M);
|
||||
|
||||
/// Adds an IR module to the Main VSO.
|
||||
/// Adds an IR module to the Main JITDylib.
|
||||
Error addIRModule(std::unique_ptr<Module> M) {
|
||||
return addIRModule(Main, std::move(M));
|
||||
}
|
||||
|
||||
/// Look up a symbol in VSO V by the symbol's linker-mangled name (to look up
|
||||
/// symbols based on their IR name use the lookup function instead).
|
||||
Expected<JITEvaluatedSymbol> lookupLinkerMangled(VSO &V, StringRef Name);
|
||||
|
||||
/// Look up a symbol in the main VSO by the symbol's linker-mangled name (to
|
||||
/// Look up a symbol in JITDylib JD by the symbol's linker-mangled name (to
|
||||
/// look up symbols based on their IR name use the lookup function instead).
|
||||
Expected<JITEvaluatedSymbol> lookupLinkerMangled(JITDylib &JD,
|
||||
StringRef Name);
|
||||
|
||||
/// Look up a symbol in the main JITDylib by the symbol's linker-mangled name
|
||||
/// (to look up symbols based on their IR name use the lookup function
|
||||
/// instead).
|
||||
Expected<JITEvaluatedSymbol> lookupLinkerMangled(StringRef Name) {
|
||||
return lookupLinkerMangled(Main, Name);
|
||||
}
|
||||
|
||||
/// Look up a symbol in VSO V based on its IR symbol name.
|
||||
Expected<JITEvaluatedSymbol> lookup(VSO &V, StringRef UnmangledName) {
|
||||
return lookupLinkerMangled(V, mangle(UnmangledName));
|
||||
/// Look up a symbol in JITDylib JD based on its IR symbol name.
|
||||
Expected<JITEvaluatedSymbol> lookup(JITDylib &JD, StringRef UnmangledName) {
|
||||
return lookupLinkerMangled(JD, mangle(UnmangledName));
|
||||
}
|
||||
|
||||
/// Look up a symbol in the main VSO based on its IR symbol name.
|
||||
/// Look up a symbol in the main JITDylib based on its IR symbol name.
|
||||
Expected<JITEvaluatedSymbol> lookup(StringRef UnmangledName) {
|
||||
return lookup(Main, UnmangledName);
|
||||
}
|
||||
|
@ -90,7 +92,7 @@ protected:
|
|||
void recordCtorDtors(Module &M);
|
||||
|
||||
std::unique_ptr<ExecutionSession> ES;
|
||||
VSO &Main;
|
||||
JITDylib &Main;
|
||||
|
||||
std::unique_ptr<TargetMachine> TM;
|
||||
DataLayout DL;
|
||||
|
@ -116,10 +118,10 @@ public:
|
|||
TransformLayer.setTransform(std::move(Transform));
|
||||
}
|
||||
|
||||
/// Add a module to be lazily compiled to VSO V.
|
||||
Error addLazyIRModule(VSO &V, std::unique_ptr<Module> M);
|
||||
/// Add a module to be lazily compiled to JITDylib JD.
|
||||
Error addLazyIRModule(JITDylib &JD, std::unique_ptr<Module> M);
|
||||
|
||||
/// Add a module to be lazily compiled to the main VSO.
|
||||
/// Add a module to be lazily compiled to the main JITDylib.
|
||||
Error addLazyIRModule(std::unique_ptr<Module> M) {
|
||||
return addLazyIRModule(Main, std::move(M));
|
||||
}
|
||||
|
|
|
@ -30,8 +30,9 @@ public:
|
|||
/// Returns the ExecutionSession for this layer.
|
||||
ExecutionSession &getExecutionSession() { return ES; }
|
||||
|
||||
/// Adds a MaterializationUnit representing the given IR to the given VSO.
|
||||
virtual Error add(VSO &V, VModuleKey K, std::unique_ptr<Module> M);
|
||||
/// Adds a MaterializationUnit representing the given IR to the given
|
||||
/// JITDylib.
|
||||
virtual Error add(JITDylib &V, VModuleKey K, std::unique_ptr<Module> M);
|
||||
|
||||
/// Emit should materialize the given IR.
|
||||
virtual void emit(MaterializationResponsibility R, VModuleKey K,
|
||||
|
@ -66,7 +67,7 @@ protected:
|
|||
SymbolNameToDefinitionMap SymbolToDefinition;
|
||||
|
||||
private:
|
||||
void discard(const VSO &V, SymbolStringPtr Name) override;
|
||||
void discard(const JITDylib &V, SymbolStringPtr Name) override;
|
||||
};
|
||||
|
||||
/// MaterializationUnit that materializes modules by calling the 'emit' method
|
||||
|
@ -92,8 +93,9 @@ public:
|
|||
/// Returns the execution session for this layer.
|
||||
ExecutionSession &getExecutionSession() { return ES; }
|
||||
|
||||
/// Adds a MaterializationUnit representing the given IR to the given VSO.
|
||||
virtual Error add(VSO &V, VModuleKey K, std::unique_ptr<MemoryBuffer> O);
|
||||
/// Adds a MaterializationUnit representing the given IR to the given
|
||||
/// JITDylib.
|
||||
virtual Error add(JITDylib &V, VModuleKey K, std::unique_ptr<MemoryBuffer> O);
|
||||
|
||||
/// Emit should materialize the given IR.
|
||||
virtual void emit(MaterializationResponsibility R, VModuleKey K,
|
||||
|
@ -117,7 +119,7 @@ public:
|
|||
private:
|
||||
|
||||
void materialize(MaterializationResponsibility R) override;
|
||||
void discard(const VSO &V, SymbolStringPtr Name) override;
|
||||
void discard(const JITDylib &V, SymbolStringPtr Name) override;
|
||||
|
||||
ObjectLayer &L;
|
||||
VModuleKey K;
|
||||
|
|
|
@ -202,7 +202,7 @@ private:
|
|||
std::move(ExtractedFunctionsModule));
|
||||
}
|
||||
|
||||
void discard(const VSO &V, SymbolStringPtr Name) override {
|
||||
void discard(const JITDylib &V, SymbolStringPtr Name) override {
|
||||
// All original symbols were materialized by the CODLayer and should be
|
||||
// final. The function bodies provided by M should never be overridden.
|
||||
llvm_unreachable("Discard should never be called on an "
|
||||
|
@ -221,7 +221,7 @@ CompileOnDemandLayer2::CompileOnDemandLayer2(
|
|||
BuildIndirectStubsManager(std::move(BuildIndirectStubsManager)),
|
||||
GetAvailableContext(std::move(GetAvailableContext)) {}
|
||||
|
||||
Error CompileOnDemandLayer2::add(VSO &V, VModuleKey K,
|
||||
Error CompileOnDemandLayer2::add(JITDylib &V, VModuleKey K,
|
||||
std::unique_ptr<Module> M) {
|
||||
return IRLayer::add(V, K, std::move(M));
|
||||
}
|
||||
|
@ -245,7 +245,7 @@ void CompileOnDemandLayer2::emit(MaterializationResponsibility R, VModuleKey K,
|
|||
// rest, and build the compile callbacks.
|
||||
std::map<SymbolStringPtr, std::pair<JITTargetAddress, JITSymbolFlags>>
|
||||
StubCallbacksAndLinkages;
|
||||
auto &TargetVSO = R.getTargetVSO();
|
||||
auto &TargetJD = R.getTargetJITDylib();
|
||||
|
||||
for (auto &F : M->functions()) {
|
||||
if (F.isDeclaration())
|
||||
|
@ -269,8 +269,8 @@ void CompileOnDemandLayer2::emit(MaterializationResponsibility R, VModuleKey K,
|
|||
auto StubName = Mangle(StubUnmangledName);
|
||||
auto BodyName = Mangle(F.getName());
|
||||
if (auto CallbackAddr = CCMgr.getCompileCallback(
|
||||
[BodyName, &TargetVSO, &ES]() -> JITTargetAddress {
|
||||
if (auto Sym = lookup({&TargetVSO}, BodyName))
|
||||
[BodyName, &TargetJD, &ES]() -> JITTargetAddress {
|
||||
if (auto Sym = lookup({&TargetJD}, BodyName))
|
||||
return Sym->getAddress();
|
||||
else {
|
||||
ES.reportError(Sym.takeError());
|
||||
|
@ -294,7 +294,7 @@ void CompileOnDemandLayer2::emit(MaterializationResponsibility R, VModuleKey K,
|
|||
StubInits[*KV.first] = KV.second;
|
||||
|
||||
// Build the function-body-extracting materialization unit.
|
||||
if (auto Err = R.getTargetVSO().define(
|
||||
if (auto Err = R.getTargetJITDylib().define(
|
||||
llvm::make_unique<ExtractingIRMaterializationUnit>(ES, *this,
|
||||
std::move(M)))) {
|
||||
ES.reportError(std::move(Err));
|
||||
|
@ -304,7 +304,7 @@ void CompileOnDemandLayer2::emit(MaterializationResponsibility R, VModuleKey K,
|
|||
|
||||
// Build the stubs.
|
||||
// FIXME: Remove function bodies materialization unit if stub creation fails.
|
||||
auto &StubsMgr = getStubsManager(TargetVSO);
|
||||
auto &StubsMgr = getStubsManager(TargetJD);
|
||||
if (auto Err = StubsMgr.createStubs(StubInits)) {
|
||||
ES.reportError(std::move(Err));
|
||||
R.failMaterialization();
|
||||
|
@ -325,7 +325,8 @@ void CompileOnDemandLayer2::emit(MaterializationResponsibility R, VModuleKey K,
|
|||
BaseLayer.emit(std::move(R), std::move(K), std::move(GlobalsModule));
|
||||
}
|
||||
|
||||
IndirectStubsManager &CompileOnDemandLayer2::getStubsManager(const VSO &V) {
|
||||
IndirectStubsManager &
|
||||
CompileOnDemandLayer2::getStubsManager(const JITDylib &V) {
|
||||
std::lock_guard<std::mutex> Lock(CODLayerMutex);
|
||||
StubManagersMap::iterator I = StubsMgrs.find(&V);
|
||||
if (I == StubsMgrs.end())
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===----- Core.cpp - Core ORC APIs (MaterializationUnit, VSO, etc.) ------===//
|
||||
//===--- Core.cpp - Core ORC APIs (MaterializationUnit, JITDylib, etc.) ---===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -102,14 +102,14 @@ raw_ostream &operator<<(raw_ostream &OS, const SymbolDependenceMap &Deps) {
|
|||
return OS;
|
||||
}
|
||||
|
||||
raw_ostream &operator<<(raw_ostream &OS, const VSOList &VSOs) {
|
||||
raw_ostream &operator<<(raw_ostream &OS, const JITDylibList &JDs) {
|
||||
OS << "[";
|
||||
if (!VSOs.empty()) {
|
||||
assert(VSOs.front() && "VSOList entries must not be null");
|
||||
OS << " " << VSOs.front()->getName();
|
||||
for (auto *V : make_range(std::next(VSOs.begin()), VSOs.end())) {
|
||||
assert(V && "VSOList entries must not be null");
|
||||
OS << ", " << V->getName();
|
||||
if (!JDs.empty()) {
|
||||
assert(JDs.front() && "JITDylibList entries must not be null");
|
||||
OS << " " << JDs.front()->getName();
|
||||
for (auto *JD : make_range(std::next(JDs.begin()), JDs.end())) {
|
||||
assert(JD && "JITDylibList entries must not be null");
|
||||
OS << ", " << JD->getName();
|
||||
}
|
||||
}
|
||||
OS << " ]";
|
||||
|
@ -291,7 +291,7 @@ Expected<SymbolMap> ExecutionSessionBase::legacyLookup(
|
|||
}
|
||||
|
||||
void ExecutionSessionBase::lookup(
|
||||
const VSOList &VSOs, const SymbolNameSet &Symbols,
|
||||
const JITDylibList &JDs, const SymbolNameSet &Symbols,
|
||||
SymbolsResolvedCallback OnResolve, SymbolsReadyCallback OnReady,
|
||||
RegisterDependenciesFunction RegisterDependencies) {
|
||||
|
||||
|
@ -301,7 +301,7 @@ void ExecutionSessionBase::lookup(
|
|||
runOutstandingMUs();
|
||||
|
||||
auto Unresolved = std::move(Symbols);
|
||||
std::map<VSO *, MaterializationUnitList> MUsMap;
|
||||
std::map<JITDylib *, MaterializationUnitList> MUsMap;
|
||||
auto Q = std::make_shared<AsynchronousSymbolQuery>(
|
||||
Symbols, std::move(OnResolve), std::move(OnReady));
|
||||
bool QueryIsFullyResolved = false;
|
||||
|
@ -309,11 +309,11 @@ void ExecutionSessionBase::lookup(
|
|||
bool QueryFailed = false;
|
||||
|
||||
runSessionLocked([&]() {
|
||||
for (auto *V : VSOs) {
|
||||
assert(V && "VSOList entries must not be null");
|
||||
assert(!MUsMap.count(V) &&
|
||||
"VSOList should not contain duplicate entries");
|
||||
V->lodgeQuery(Q, Unresolved, MUsMap[V]);
|
||||
for (auto *JD : JDs) {
|
||||
assert(JD && "JITDylibList entries must not be null");
|
||||
assert(!MUsMap.count(JD) &&
|
||||
"JITDylibList should not contain duplicate entries");
|
||||
JD->lodgeQuery(Q, Unresolved, MUsMap[JD]);
|
||||
}
|
||||
|
||||
if (Unresolved.empty()) {
|
||||
|
@ -364,10 +364,9 @@ void ExecutionSessionBase::lookup(
|
|||
runOutstandingMUs();
|
||||
}
|
||||
|
||||
Expected<SymbolMap>
|
||||
ExecutionSessionBase::lookup(const VSOList &VSOs, const SymbolNameSet &Symbols,
|
||||
RegisterDependenciesFunction RegisterDependencies,
|
||||
bool WaitUntilReady) {
|
||||
Expected<SymbolMap> ExecutionSessionBase::lookup(
|
||||
const JITDylibList &JDs, const SymbolNameSet &Symbols,
|
||||
RegisterDependenciesFunction RegisterDependencies, bool WaitUntilReady) {
|
||||
#if LLVM_ENABLE_THREADS
|
||||
// In the threaded case we use promises to return the results.
|
||||
std::promise<SymbolMap> PromisedResult;
|
||||
|
@ -434,7 +433,7 @@ ExecutionSessionBase::lookup(const VSOList &VSOs, const SymbolNameSet &Symbols,
|
|||
#endif
|
||||
|
||||
// Perform the asynchronous lookup.
|
||||
lookup(VSOs, Symbols, OnResolve, OnReady, RegisterDependencies);
|
||||
lookup(JDs, Symbols, OnResolve, OnReady, RegisterDependencies);
|
||||
|
||||
#if LLVM_ENABLE_THREADS
|
||||
auto ResultFuture = PromisedResult.get_future();
|
||||
|
@ -479,19 +478,20 @@ ExecutionSessionBase::lookup(const VSOList &VSOs, const SymbolNameSet &Symbols,
|
|||
|
||||
void ExecutionSessionBase::runOutstandingMUs() {
|
||||
while (1) {
|
||||
std::pair<VSO *, std::unique_ptr<MaterializationUnit>> VSOAndMU;
|
||||
std::pair<JITDylib *, std::unique_ptr<MaterializationUnit>> JITDylibAndMU;
|
||||
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
|
||||
if (!OutstandingMUs.empty()) {
|
||||
VSOAndMU = std::move(OutstandingMUs.back());
|
||||
JITDylibAndMU = std::move(OutstandingMUs.back());
|
||||
OutstandingMUs.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
if (VSOAndMU.first) {
|
||||
assert(VSOAndMU.second && "VSO, but no MU?");
|
||||
dispatchMaterialization(*VSOAndMU.first, std::move(VSOAndMU.second));
|
||||
if (JITDylibAndMU.first) {
|
||||
assert(JITDylibAndMU.second && "JITDylib, but no MU?");
|
||||
dispatchMaterialization(*JITDylibAndMU.first,
|
||||
std::move(JITDylibAndMU.second));
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
@ -557,17 +557,19 @@ void AsynchronousSymbolQuery::handleFailed(Error Err) {
|
|||
NotifySymbolsReady = SymbolsReadyCallback();
|
||||
}
|
||||
|
||||
void AsynchronousSymbolQuery::addQueryDependence(VSO &V, SymbolStringPtr Name) {
|
||||
bool Added = QueryRegistrations[&V].insert(std::move(Name)).second;
|
||||
void AsynchronousSymbolQuery::addQueryDependence(JITDylib &JD,
|
||||
SymbolStringPtr Name) {
|
||||
bool Added = QueryRegistrations[&JD].insert(std::move(Name)).second;
|
||||
(void)Added;
|
||||
assert(Added && "Duplicate dependence notification?");
|
||||
}
|
||||
|
||||
void AsynchronousSymbolQuery::removeQueryDependence(
|
||||
VSO &V, const SymbolStringPtr &Name) {
|
||||
auto QRI = QueryRegistrations.find(&V);
|
||||
assert(QRI != QueryRegistrations.end() && "No dependencies registered for V");
|
||||
assert(QRI->second.count(Name) && "No dependency on Name in V");
|
||||
JITDylib &JD, const SymbolStringPtr &Name) {
|
||||
auto QRI = QueryRegistrations.find(&JD);
|
||||
assert(QRI != QueryRegistrations.end() &&
|
||||
"No dependencies registered for JD");
|
||||
assert(QRI->second.count(Name) && "No dependency on Name in JD");
|
||||
QRI->second.erase(Name);
|
||||
if (QRI->second.empty())
|
||||
QueryRegistrations.erase(QRI);
|
||||
|
@ -583,8 +585,8 @@ void AsynchronousSymbolQuery::detach() {
|
|||
}
|
||||
|
||||
MaterializationResponsibility::MaterializationResponsibility(
|
||||
VSO &V, SymbolFlagsMap SymbolFlags)
|
||||
: V(V), SymbolFlags(std::move(SymbolFlags)) {
|
||||
JITDylib &JD, SymbolFlagsMap SymbolFlags)
|
||||
: JD(JD), SymbolFlags(std::move(SymbolFlags)) {
|
||||
assert(!this->SymbolFlags.empty() && "Materializing nothing?");
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
@ -599,7 +601,7 @@ MaterializationResponsibility::~MaterializationResponsibility() {
|
|||
}
|
||||
|
||||
SymbolNameSet MaterializationResponsibility::getRequestedSymbols() {
|
||||
return V.getRequestedSymbols(SymbolFlags);
|
||||
return JD.getRequestedSymbols(SymbolFlags);
|
||||
}
|
||||
|
||||
void MaterializationResponsibility::resolve(const SymbolMap &Symbols) {
|
||||
|
@ -619,7 +621,7 @@ void MaterializationResponsibility::resolve(const SymbolMap &Symbols) {
|
|||
}
|
||||
#endif
|
||||
|
||||
V.resolve(Symbols);
|
||||
JD.resolve(Symbols);
|
||||
}
|
||||
|
||||
void MaterializationResponsibility::finalize() {
|
||||
|
@ -629,7 +631,7 @@ void MaterializationResponsibility::finalize() {
|
|||
"Failed to resolve symbol before finalization");
|
||||
#endif // NDEBUG
|
||||
|
||||
V.finalize(SymbolFlags);
|
||||
JD.finalize(SymbolFlags);
|
||||
SymbolFlags.clear();
|
||||
}
|
||||
|
||||
|
@ -637,8 +639,8 @@ Error MaterializationResponsibility::defineMaterializing(
|
|||
const SymbolFlagsMap &NewSymbolFlags) {
|
||||
// Add the given symbols to this responsibility object.
|
||||
// It's ok if we hit a duplicate here: In that case the new version will be
|
||||
// discarded, and the VSO::defineMaterializing method will return a duplicate
|
||||
// symbol error.
|
||||
// discarded, and the JITDylib::defineMaterializing method will return a
|
||||
// duplicate symbol error.
|
||||
for (auto &KV : NewSymbolFlags) {
|
||||
auto I = SymbolFlags.insert(KV).first;
|
||||
(void)I;
|
||||
|
@ -647,7 +649,7 @@ Error MaterializationResponsibility::defineMaterializing(
|
|||
#endif
|
||||
}
|
||||
|
||||
return V.defineMaterializing(NewSymbolFlags);
|
||||
return JD.defineMaterializing(NewSymbolFlags);
|
||||
}
|
||||
|
||||
void MaterializationResponsibility::failMaterialization() {
|
||||
|
@ -656,7 +658,7 @@ void MaterializationResponsibility::failMaterialization() {
|
|||
for (auto &KV : SymbolFlags)
|
||||
FailedSymbols.insert(KV.first);
|
||||
|
||||
V.notifyFailed(FailedSymbols);
|
||||
JD.notifyFailed(FailedSymbols);
|
||||
SymbolFlags.clear();
|
||||
}
|
||||
|
||||
|
@ -665,7 +667,7 @@ void MaterializationResponsibility::replace(
|
|||
for (auto &KV : MU->getSymbols())
|
||||
SymbolFlags.erase(KV.first);
|
||||
|
||||
V.replace(std::move(MU));
|
||||
JD.replace(std::move(MU));
|
||||
}
|
||||
|
||||
MaterializationResponsibility
|
||||
|
@ -682,20 +684,20 @@ MaterializationResponsibility::delegate(const SymbolNameSet &Symbols) {
|
|||
SymbolFlags.erase(I);
|
||||
}
|
||||
|
||||
return MaterializationResponsibility(V, std::move(DelegatedFlags));
|
||||
return MaterializationResponsibility(JD, std::move(DelegatedFlags));
|
||||
}
|
||||
|
||||
void MaterializationResponsibility::addDependencies(
|
||||
const SymbolStringPtr &Name, const SymbolDependenceMap &Dependencies) {
|
||||
assert(SymbolFlags.count(Name) &&
|
||||
"Symbol not covered by this MaterializationResponsibility instance");
|
||||
V.addDependencies(Name, Dependencies);
|
||||
JD.addDependencies(Name, Dependencies);
|
||||
}
|
||||
|
||||
void MaterializationResponsibility::addDependenciesForAll(
|
||||
const SymbolDependenceMap &Dependencies) {
|
||||
for (auto &KV : SymbolFlags)
|
||||
V.addDependencies(KV.first, Dependencies);
|
||||
JD.addDependencies(KV.first, Dependencies);
|
||||
}
|
||||
|
||||
AbsoluteSymbolsMaterializationUnit::AbsoluteSymbolsMaterializationUnit(
|
||||
|
@ -708,7 +710,7 @@ void AbsoluteSymbolsMaterializationUnit::materialize(
|
|||
R.finalize();
|
||||
}
|
||||
|
||||
void AbsoluteSymbolsMaterializationUnit::discard(const VSO &V,
|
||||
void AbsoluteSymbolsMaterializationUnit::discard(const JITDylib &JD,
|
||||
SymbolStringPtr Name) {
|
||||
assert(Symbols.count(Name) && "Symbol is not part of this MU");
|
||||
Symbols.erase(Name);
|
||||
|
@ -723,19 +725,20 @@ AbsoluteSymbolsMaterializationUnit::extractFlags(const SymbolMap &Symbols) {
|
|||
}
|
||||
|
||||
ReExportsMaterializationUnit::ReExportsMaterializationUnit(
|
||||
VSO *SourceVSO, SymbolAliasMap Aliases)
|
||||
: MaterializationUnit(extractFlags(Aliases)), SourceVSO(SourceVSO),
|
||||
JITDylib *SourceJD, SymbolAliasMap Aliases)
|
||||
: MaterializationUnit(extractFlags(Aliases)), SourceJD(SourceJD),
|
||||
Aliases(std::move(Aliases)) {}
|
||||
|
||||
void ReExportsMaterializationUnit::materialize(
|
||||
MaterializationResponsibility R) {
|
||||
|
||||
auto &ES = R.getTargetVSO().getExecutionSession();
|
||||
VSO &TgtV = R.getTargetVSO();
|
||||
VSO &SrcV = SourceVSO ? *SourceVSO : TgtV;
|
||||
auto &ES = R.getTargetJITDylib().getExecutionSession();
|
||||
JITDylib &TgtJD = R.getTargetJITDylib();
|
||||
JITDylib &SrcJD = SourceJD ? *SourceJD : TgtJD;
|
||||
|
||||
// Find the set of requested aliases and aliasees. Return any unrequested
|
||||
// aliases back to the VSO so as to not prematurely materialize any aliasees.
|
||||
// aliases back to the JITDylib so as to not prematurely materialize any
|
||||
// aliasees.
|
||||
auto RequestedSymbols = R.getRequestedSymbols();
|
||||
SymbolAliasMap RequestedAliases;
|
||||
|
||||
|
@ -747,8 +750,8 @@ void ReExportsMaterializationUnit::materialize(
|
|||
}
|
||||
|
||||
if (!Aliases.empty()) {
|
||||
if (SourceVSO)
|
||||
R.replace(reexports(*SourceVSO, std::move(Aliases)));
|
||||
if (SourceJD)
|
||||
R.replace(reexports(*SourceJD, std::move(Aliases)));
|
||||
else
|
||||
R.replace(symbolAliases(std::move(Aliases)));
|
||||
}
|
||||
|
@ -781,8 +784,8 @@ void ReExportsMaterializationUnit::materialize(
|
|||
auto Tmp = I++;
|
||||
|
||||
// Chain detected. Skip this symbol for this round.
|
||||
if (&SrcV == &TgtV && (QueryAliases.count(Tmp->second.Aliasee) ||
|
||||
RequestedAliases.count(Tmp->second.Aliasee)))
|
||||
if (&SrcJD == &TgtJD && (QueryAliases.count(Tmp->second.Aliasee) ||
|
||||
RequestedAliases.count(Tmp->second.Aliasee)))
|
||||
continue;
|
||||
|
||||
ResponsibilitySymbols.insert(Tmp->first);
|
||||
|
@ -806,21 +809,21 @@ void ReExportsMaterializationUnit::materialize(
|
|||
QueryInfos.pop_back();
|
||||
|
||||
auto RegisterDependencies = [QueryInfo,
|
||||
&SrcV](const SymbolDependenceMap &Deps) {
|
||||
&SrcJD](const SymbolDependenceMap &Deps) {
|
||||
// If there were no materializing symbols, just bail out.
|
||||
if (Deps.empty())
|
||||
return;
|
||||
|
||||
// Otherwise the only deps should be on SrcV.
|
||||
assert(Deps.size() == 1 && Deps.count(&SrcV) &&
|
||||
// Otherwise the only deps should be on SrcJD.
|
||||
assert(Deps.size() == 1 && Deps.count(&SrcJD) &&
|
||||
"Unexpected dependencies for reexports");
|
||||
|
||||
auto &SrcVDeps = Deps.find(&SrcV)->second;
|
||||
auto &SrcJDDeps = Deps.find(&SrcJD)->second;
|
||||
SymbolDependenceMap PerAliasDepsMap;
|
||||
auto &PerAliasDeps = PerAliasDepsMap[&SrcV];
|
||||
auto &PerAliasDeps = PerAliasDepsMap[&SrcJD];
|
||||
|
||||
for (auto &KV : QueryInfo->Aliases)
|
||||
if (SrcVDeps.count(KV.second.Aliasee)) {
|
||||
if (SrcJDDeps.count(KV.second.Aliasee)) {
|
||||
PerAliasDeps = {KV.second.Aliasee};
|
||||
QueryInfo->R.addDependencies(KV.first, PerAliasDepsMap);
|
||||
}
|
||||
|
@ -838,7 +841,7 @@ void ReExportsMaterializationUnit::materialize(
|
|||
QueryInfo->R.resolve(ResolutionMap);
|
||||
QueryInfo->R.finalize();
|
||||
} else {
|
||||
auto &ES = QueryInfo->R.getTargetVSO().getExecutionSession();
|
||||
auto &ES = QueryInfo->R.getTargetJITDylib().getExecutionSession();
|
||||
ES.reportError(Result.takeError());
|
||||
QueryInfo->R.failMaterialization();
|
||||
}
|
||||
|
@ -846,12 +849,13 @@ void ReExportsMaterializationUnit::materialize(
|
|||
|
||||
auto OnReady = [&ES](Error Err) { ES.reportError(std::move(Err)); };
|
||||
|
||||
ES.lookup({&SrcV}, QuerySymbols, std::move(OnResolve), std::move(OnReady),
|
||||
ES.lookup({&SrcJD}, QuerySymbols, std::move(OnResolve), std::move(OnReady),
|
||||
std::move(RegisterDependencies));
|
||||
}
|
||||
}
|
||||
|
||||
void ReExportsMaterializationUnit::discard(const VSO &V, SymbolStringPtr Name) {
|
||||
void ReExportsMaterializationUnit::discard(const JITDylib &JD,
|
||||
SymbolStringPtr Name) {
|
||||
assert(Aliases.count(Name) &&
|
||||
"Symbol not covered by this MaterializationUnit");
|
||||
Aliases.erase(Name);
|
||||
|
@ -867,8 +871,8 @@ ReExportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) {
|
|||
}
|
||||
|
||||
Expected<SymbolAliasMap>
|
||||
buildSimpleReexportsAliasMap(VSO &SourceV, const SymbolNameSet &Symbols) {
|
||||
auto Flags = SourceV.lookupFlags(Symbols);
|
||||
buildSimpleReexportsAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols) {
|
||||
auto Flags = SourceJD.lookupFlags(Symbols);
|
||||
|
||||
if (Flags.size() != Symbols.size()) {
|
||||
SymbolNameSet Unresolved = Symbols;
|
||||
|
@ -887,15 +891,15 @@ buildSimpleReexportsAliasMap(VSO &SourceV, const SymbolNameSet &Symbols) {
|
|||
}
|
||||
|
||||
ReexportsFallbackDefinitionGenerator::ReexportsFallbackDefinitionGenerator(
|
||||
VSO &BackingVSO, SymbolPredicate Allow)
|
||||
: BackingVSO(BackingVSO), Allow(std::move(Allow)) {}
|
||||
JITDylib &BackingJD, SymbolPredicate Allow)
|
||||
: BackingJD(BackingJD), Allow(std::move(Allow)) {}
|
||||
|
||||
SymbolNameSet ReexportsFallbackDefinitionGenerator::
|
||||
operator()(VSO &V, const SymbolNameSet &Names) {
|
||||
operator()(JITDylib &JD, const SymbolNameSet &Names) {
|
||||
orc::SymbolNameSet Added;
|
||||
orc::SymbolAliasMap AliasMap;
|
||||
|
||||
auto Flags = BackingVSO.lookupFlags(Names);
|
||||
auto Flags = BackingJD.lookupFlags(Names);
|
||||
|
||||
for (auto &KV : Flags) {
|
||||
if (!Allow(KV.first))
|
||||
|
@ -905,12 +909,12 @@ operator()(VSO &V, const SymbolNameSet &Names) {
|
|||
}
|
||||
|
||||
if (!Added.empty())
|
||||
cantFail(V.define(reexports(BackingVSO, AliasMap)));
|
||||
cantFail(JD.define(reexports(BackingJD, AliasMap)));
|
||||
|
||||
return Added;
|
||||
}
|
||||
|
||||
Error VSO::defineMaterializing(const SymbolFlagsMap &SymbolFlags) {
|
||||
Error JITDylib::defineMaterializing(const SymbolFlagsMap &SymbolFlags) {
|
||||
return ES.runSessionLocked([&]() -> Error {
|
||||
std::vector<SymbolMap::iterator> AddedSyms;
|
||||
|
||||
|
@ -940,7 +944,7 @@ Error VSO::defineMaterializing(const SymbolFlagsMap &SymbolFlags) {
|
|||
});
|
||||
}
|
||||
|
||||
void VSO::replace(std::unique_ptr<MaterializationUnit> MU) {
|
||||
void JITDylib::replace(std::unique_ptr<MaterializationUnit> MU) {
|
||||
assert(MU != nullptr && "Can not replace with a null MaterializationUnit");
|
||||
|
||||
auto MustRunMU =
|
||||
|
@ -991,12 +995,12 @@ void VSO::replace(std::unique_ptr<MaterializationUnit> MU) {
|
|||
ES.dispatchMaterialization(*this, std::move(MustRunMU));
|
||||
}
|
||||
|
||||
SymbolNameSet VSO::getRequestedSymbols(const SymbolFlagsMap &SymbolFlags) {
|
||||
SymbolNameSet JITDylib::getRequestedSymbols(const SymbolFlagsMap &SymbolFlags) {
|
||||
return ES.runSessionLocked([&]() {
|
||||
SymbolNameSet RequestedSymbols;
|
||||
|
||||
for (auto &KV : SymbolFlags) {
|
||||
assert(Symbols.count(KV.first) && "VSO does not cover this symbol?");
|
||||
assert(Symbols.count(KV.first) && "JITDylib does not cover this symbol?");
|
||||
assert(Symbols[KV.first].getFlags().isMaterializing() &&
|
||||
"getRequestedSymbols can only be called for materializing "
|
||||
"symbols");
|
||||
|
@ -1012,8 +1016,8 @@ SymbolNameSet VSO::getRequestedSymbols(const SymbolFlagsMap &SymbolFlags) {
|
|||
});
|
||||
}
|
||||
|
||||
void VSO::addDependencies(const SymbolStringPtr &Name,
|
||||
const SymbolDependenceMap &Dependencies) {
|
||||
void JITDylib::addDependencies(const SymbolStringPtr &Name,
|
||||
const SymbolDependenceMap &Dependencies) {
|
||||
assert(Symbols.count(Name) && "Name not in symbol table");
|
||||
assert((Symbols[Name].getFlags().isLazy() ||
|
||||
Symbols[Name].getFlags().isMaterializing()) &&
|
||||
|
@ -1023,36 +1027,36 @@ void VSO::addDependencies(const SymbolStringPtr &Name,
|
|||
assert(!MI.IsFinalized && "Can not add dependencies to finalized symbol");
|
||||
|
||||
for (auto &KV : Dependencies) {
|
||||
assert(KV.first && "Null VSO in dependency?");
|
||||
auto &OtherVSO = *KV.first;
|
||||
auto &DepsOnOtherVSO = MI.UnfinalizedDependencies[&OtherVSO];
|
||||
assert(KV.first && "Null JITDylib in dependency?");
|
||||
auto &OtherJITDylib = *KV.first;
|
||||
auto &DepsOnOtherJITDylib = MI.UnfinalizedDependencies[&OtherJITDylib];
|
||||
|
||||
for (auto &OtherSymbol : KV.second) {
|
||||
#ifndef NDEBUG
|
||||
// Assert that this symbol exists and has not been finalized already.
|
||||
auto SymI = OtherVSO.Symbols.find(OtherSymbol);
|
||||
assert(SymI != OtherVSO.Symbols.end() &&
|
||||
auto SymI = OtherJITDylib.Symbols.find(OtherSymbol);
|
||||
assert(SymI != OtherJITDylib.Symbols.end() &&
|
||||
(SymI->second.getFlags().isLazy() ||
|
||||
SymI->second.getFlags().isMaterializing()) &&
|
||||
"Dependency on finalized symbol");
|
||||
#endif
|
||||
|
||||
auto &OtherMI = OtherVSO.MaterializingInfos[OtherSymbol];
|
||||
auto &OtherMI = OtherJITDylib.MaterializingInfos[OtherSymbol];
|
||||
|
||||
if (OtherMI.IsFinalized)
|
||||
transferFinalizedNodeDependencies(MI, Name, OtherMI);
|
||||
else if (&OtherVSO != this || OtherSymbol != Name) {
|
||||
else if (&OtherJITDylib != this || OtherSymbol != Name) {
|
||||
OtherMI.Dependants[this].insert(Name);
|
||||
DepsOnOtherVSO.insert(OtherSymbol);
|
||||
DepsOnOtherJITDylib.insert(OtherSymbol);
|
||||
}
|
||||
}
|
||||
|
||||
if (DepsOnOtherVSO.empty())
|
||||
MI.UnfinalizedDependencies.erase(&OtherVSO);
|
||||
if (DepsOnOtherJITDylib.empty())
|
||||
MI.UnfinalizedDependencies.erase(&OtherJITDylib);
|
||||
}
|
||||
}
|
||||
|
||||
void VSO::resolve(const SymbolMap &Resolved) {
|
||||
void JITDylib::resolve(const SymbolMap &Resolved) {
|
||||
auto FullyResolvedQueries = ES.runSessionLocked([&, this]() {
|
||||
AsynchronousSymbolQuerySet FullyResolvedQueries;
|
||||
for (const auto &KV : Resolved) {
|
||||
|
@ -1098,7 +1102,7 @@ void VSO::resolve(const SymbolMap &Resolved) {
|
|||
}
|
||||
}
|
||||
|
||||
void VSO::finalize(const SymbolFlagsMap &Finalized) {
|
||||
void JITDylib::finalize(const SymbolFlagsMap &Finalized) {
|
||||
auto FullyReadyQueries = ES.runSessionLocked([&, this]() {
|
||||
AsynchronousSymbolQuerySet ReadyQueries;
|
||||
|
||||
|
@ -1115,11 +1119,11 @@ void VSO::finalize(const SymbolFlagsMap &Finalized) {
|
|||
// it. If the dependant node is fully finalized then notify any pending
|
||||
// queries.
|
||||
for (auto &KV : MI.Dependants) {
|
||||
auto &DependantVSO = *KV.first;
|
||||
auto &DependantJD = *KV.first;
|
||||
for (auto &DependantName : KV.second) {
|
||||
auto DependantMII =
|
||||
DependantVSO.MaterializingInfos.find(DependantName);
|
||||
assert(DependantMII != DependantVSO.MaterializingInfos.end() &&
|
||||
DependantJD.MaterializingInfos.find(DependantName);
|
||||
assert(DependantMII != DependantJD.MaterializingInfos.end() &&
|
||||
"Dependant should have MaterializingInfo");
|
||||
|
||||
auto &DependantMI = DependantMII->second;
|
||||
|
@ -1132,8 +1136,8 @@ void VSO::finalize(const SymbolFlagsMap &Finalized) {
|
|||
DependantMI.UnfinalizedDependencies.erase(this);
|
||||
|
||||
// Transfer unfinalized dependencies from this node to the dependant.
|
||||
DependantVSO.transferFinalizedNodeDependencies(DependantMI,
|
||||
DependantName, MI);
|
||||
DependantJD.transferFinalizedNodeDependencies(DependantMI,
|
||||
DependantName, MI);
|
||||
|
||||
// If the dependant is finalized and this node was the last of its
|
||||
// unfinalized dependencies then notify any pending queries on the
|
||||
|
@ -1146,17 +1150,17 @@ void VSO::finalize(const SymbolFlagsMap &Finalized) {
|
|||
Q->notifySymbolReady();
|
||||
if (Q->isFullyReady())
|
||||
ReadyQueries.insert(Q);
|
||||
Q->removeQueryDependence(DependantVSO, DependantName);
|
||||
Q->removeQueryDependence(DependantJD, DependantName);
|
||||
}
|
||||
|
||||
// If this dependant node was fully finalized we can erase its
|
||||
// MaterializingInfo and update its materializing state.
|
||||
assert(DependantVSO.Symbols.count(DependantName) &&
|
||||
assert(DependantJD.Symbols.count(DependantName) &&
|
||||
"Dependant has no entry in the Symbols table");
|
||||
auto &DependantSym = DependantVSO.Symbols[DependantName];
|
||||
auto &DependantSym = DependantJD.Symbols[DependantName];
|
||||
DependantSym.setFlags(static_cast<JITSymbolFlags::FlagNames>(
|
||||
DependantSym.getFlags() & ~JITSymbolFlags::Materializing));
|
||||
DependantVSO.MaterializingInfos.erase(DependantMII);
|
||||
DependantJD.MaterializingInfos.erase(DependantMII);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1188,7 +1192,7 @@ void VSO::finalize(const SymbolFlagsMap &Finalized) {
|
|||
}
|
||||
}
|
||||
|
||||
void VSO::notifyFailed(const SymbolNameSet &FailedSymbols) {
|
||||
void JITDylib::notifyFailed(const SymbolNameSet &FailedSymbols) {
|
||||
|
||||
// FIXME: This should fail any transitively dependant symbols too.
|
||||
|
||||
|
@ -1197,7 +1201,7 @@ void VSO::notifyFailed(const SymbolNameSet &FailedSymbols) {
|
|||
|
||||
for (auto &Name : FailedSymbols) {
|
||||
auto I = Symbols.find(Name);
|
||||
assert(I != Symbols.end() && "Symbol not present in this VSO");
|
||||
assert(I != Symbols.end() && "Symbol not present in this JITDylib");
|
||||
Symbols.erase(I);
|
||||
|
||||
auto MII = MaterializingInfos.find(Name);
|
||||
|
@ -1230,35 +1234,36 @@ void VSO::notifyFailed(const SymbolNameSet &FailedSymbols) {
|
|||
Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbols));
|
||||
}
|
||||
|
||||
void VSO::setSearchOrder(VSOList NewSearchOrder, bool SearchThisVSOFirst) {
|
||||
if (SearchThisVSOFirst && NewSearchOrder.front() != this)
|
||||
void JITDylib::setSearchOrder(JITDylibList NewSearchOrder,
|
||||
bool SearchThisJITDylibFirst) {
|
||||
if (SearchThisJITDylibFirst && NewSearchOrder.front() != this)
|
||||
NewSearchOrder.insert(NewSearchOrder.begin(), this);
|
||||
|
||||
ES.runSessionLocked([&]() { SearchOrder = std::move(NewSearchOrder); });
|
||||
}
|
||||
|
||||
void VSO::addToSearchOrder(VSO &V) {
|
||||
ES.runSessionLocked([&]() { SearchOrder.push_back(&V); });
|
||||
void JITDylib::addToSearchOrder(JITDylib &JD) {
|
||||
ES.runSessionLocked([&]() { SearchOrder.push_back(&JD); });
|
||||
}
|
||||
|
||||
void VSO::replaceInSearchOrder(VSO &OldV, VSO &NewV) {
|
||||
void JITDylib::replaceInSearchOrder(JITDylib &OldJD, JITDylib &NewJD) {
|
||||
ES.runSessionLocked([&]() {
|
||||
auto I = std::find(SearchOrder.begin(), SearchOrder.end(), &OldV);
|
||||
auto I = std::find(SearchOrder.begin(), SearchOrder.end(), &OldJD);
|
||||
|
||||
if (I != SearchOrder.end())
|
||||
*I = &NewV;
|
||||
*I = &NewJD;
|
||||
});
|
||||
}
|
||||
|
||||
void VSO::removeFromSearchOrder(VSO &V) {
|
||||
void JITDylib::removeFromSearchOrder(JITDylib &JD) {
|
||||
ES.runSessionLocked([&]() {
|
||||
auto I = std::find(SearchOrder.begin(), SearchOrder.end(), &V);
|
||||
auto I = std::find(SearchOrder.begin(), SearchOrder.end(), &JD);
|
||||
if (I != SearchOrder.end())
|
||||
SearchOrder.erase(I);
|
||||
});
|
||||
}
|
||||
|
||||
SymbolFlagsMap VSO::lookupFlags(const SymbolNameSet &Names) {
|
||||
SymbolFlagsMap JITDylib::lookupFlags(const SymbolNameSet &Names) {
|
||||
return ES.runSessionLocked([&, this]() {
|
||||
SymbolFlagsMap Result;
|
||||
auto Unresolved = lookupFlagsImpl(Result, Names);
|
||||
|
@ -1275,8 +1280,8 @@ SymbolFlagsMap VSO::lookupFlags(const SymbolNameSet &Names) {
|
|||
});
|
||||
}
|
||||
|
||||
SymbolNameSet VSO::lookupFlagsImpl(SymbolFlagsMap &Flags,
|
||||
const SymbolNameSet &Names) {
|
||||
SymbolNameSet JITDylib::lookupFlagsImpl(SymbolFlagsMap &Flags,
|
||||
const SymbolNameSet &Names) {
|
||||
SymbolNameSet Unresolved;
|
||||
|
||||
for (auto &Name : Names) {
|
||||
|
@ -1294,8 +1299,9 @@ SymbolNameSet VSO::lookupFlagsImpl(SymbolFlagsMap &Flags,
|
|||
return Unresolved;
|
||||
}
|
||||
|
||||
void VSO::lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q,
|
||||
SymbolNameSet &Unresolved, MaterializationUnitList &MUs) {
|
||||
void JITDylib::lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q,
|
||||
SymbolNameSet &Unresolved,
|
||||
MaterializationUnitList &MUs) {
|
||||
assert(Q && "Query can not be null");
|
||||
|
||||
lodgeQueryImpl(Q, Unresolved, MUs);
|
||||
|
@ -1311,7 +1317,7 @@ void VSO::lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q,
|
|||
}
|
||||
}
|
||||
|
||||
void VSO::lodgeQueryImpl(
|
||||
void JITDylib::lodgeQueryImpl(
|
||||
std::shared_ptr<AsynchronousSymbolQuery> &Q, SymbolNameSet &Unresolved,
|
||||
std::vector<std::unique_ptr<MaterializationUnit>> &MUs) {
|
||||
for (auto I = Unresolved.begin(), E = Unresolved.end(); I != E;) {
|
||||
|
@ -1323,7 +1329,7 @@ void VSO::lodgeQueryImpl(
|
|||
if (SymI == Symbols.end())
|
||||
continue;
|
||||
|
||||
// If we found Name in V, remove it frome the Unresolved set and add it
|
||||
// If we found Name in JD, remove it frome the Unresolved set and add it
|
||||
// to the added set.
|
||||
Unresolved.erase(TmpI);
|
||||
|
||||
|
@ -1372,8 +1378,8 @@ void VSO::lodgeQueryImpl(
|
|||
}
|
||||
}
|
||||
|
||||
SymbolNameSet VSO::legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
|
||||
SymbolNameSet Names) {
|
||||
SymbolNameSet JITDylib::legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
|
||||
SymbolNameSet Names) {
|
||||
assert(Q && "Query can not be null");
|
||||
|
||||
ES.runOutstandingMUs();
|
||||
|
@ -1424,10 +1430,10 @@ SymbolNameSet VSO::legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
|
|||
return Unresolved;
|
||||
}
|
||||
|
||||
VSO::LookupImplActionFlags
|
||||
VSO::lookupImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
|
||||
std::vector<std::unique_ptr<MaterializationUnit>> &MUs,
|
||||
SymbolNameSet &Unresolved) {
|
||||
JITDylib::LookupImplActionFlags
|
||||
JITDylib::lookupImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
|
||||
std::vector<std::unique_ptr<MaterializationUnit>> &MUs,
|
||||
SymbolNameSet &Unresolved) {
|
||||
LookupImplActionFlags ActionFlags = None;
|
||||
|
||||
for (auto I = Unresolved.begin(), E = Unresolved.end(); I != E;) {
|
||||
|
@ -1439,7 +1445,7 @@ VSO::lookupImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
|
|||
if (SymI == Symbols.end())
|
||||
continue;
|
||||
|
||||
// If we found Name in V, remove it frome the Unresolved set and add it
|
||||
// If we found Name, remove it frome the Unresolved set and add it
|
||||
// to the dependencies set.
|
||||
Unresolved.erase(TmpI);
|
||||
|
||||
|
@ -1495,9 +1501,9 @@ VSO::lookupImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
|
|||
return ActionFlags;
|
||||
}
|
||||
|
||||
void VSO::dump(raw_ostream &OS) {
|
||||
void JITDylib::dump(raw_ostream &OS) {
|
||||
ES.runSessionLocked([&, this]() {
|
||||
OS << "VSO \"" << VSOName
|
||||
OS << "JITDylib \"" << JITDylibName
|
||||
<< "\" (ES: " << format("0x%016x", reinterpret_cast<uintptr_t>(&ES))
|
||||
<< "):\n"
|
||||
<< "Symbol table:\n";
|
||||
|
@ -1541,12 +1547,12 @@ void VSO::dump(raw_ostream &OS) {
|
|||
});
|
||||
}
|
||||
|
||||
VSO::VSO(ExecutionSessionBase &ES, std::string Name)
|
||||
: ES(ES), VSOName(std::move(Name)) {
|
||||
JITDylib::JITDylib(ExecutionSessionBase &ES, std::string Name)
|
||||
: ES(ES), JITDylibName(std::move(Name)) {
|
||||
SearchOrder.push_back(this);
|
||||
}
|
||||
|
||||
Error VSO::defineImpl(MaterializationUnit &MU) {
|
||||
Error JITDylib::defineImpl(MaterializationUnit &MU) {
|
||||
SymbolNameSet Duplicates;
|
||||
SymbolNameSet MUDefsOverridden;
|
||||
|
||||
|
@ -1623,8 +1629,8 @@ Error VSO::defineImpl(MaterializationUnit &MU) {
|
|||
return Error::success();
|
||||
}
|
||||
|
||||
void VSO::detachQueryHelper(AsynchronousSymbolQuery &Q,
|
||||
const SymbolNameSet &QuerySymbols) {
|
||||
void JITDylib::detachQueryHelper(AsynchronousSymbolQuery &Q,
|
||||
const SymbolNameSet &QuerySymbols) {
|
||||
for (auto &QuerySymbol : QuerySymbols) {
|
||||
assert(MaterializingInfos.count(QuerySymbol) &&
|
||||
"QuerySymbol does not have MaterializingInfo");
|
||||
|
@ -1643,53 +1649,55 @@ void VSO::detachQueryHelper(AsynchronousSymbolQuery &Q,
|
|||
}
|
||||
}
|
||||
|
||||
void VSO::transferFinalizedNodeDependencies(
|
||||
void JITDylib::transferFinalizedNodeDependencies(
|
||||
MaterializingInfo &DependantMI, const SymbolStringPtr &DependantName,
|
||||
MaterializingInfo &FinalizedMI) {
|
||||
for (auto &KV : FinalizedMI.UnfinalizedDependencies) {
|
||||
auto &DependencyVSO = *KV.first;
|
||||
SymbolNameSet *UnfinalizedDependenciesOnDependencyVSO = nullptr;
|
||||
auto &DependencyJD = *KV.first;
|
||||
SymbolNameSet *UnfinalizedDependenciesOnDependencyJD = nullptr;
|
||||
|
||||
for (auto &DependencyName : KV.second) {
|
||||
auto &DependencyMI = DependencyVSO.MaterializingInfos[DependencyName];
|
||||
auto &DependencyMI = DependencyJD.MaterializingInfos[DependencyName];
|
||||
|
||||
// Do not add self dependencies.
|
||||
if (&DependencyMI == &DependantMI)
|
||||
continue;
|
||||
|
||||
// If we haven't looked up the dependencies for DependencyVSO yet, do it
|
||||
// If we haven't looked up the dependencies for DependencyJD yet, do it
|
||||
// now and cache the result.
|
||||
if (!UnfinalizedDependenciesOnDependencyVSO)
|
||||
UnfinalizedDependenciesOnDependencyVSO =
|
||||
&DependantMI.UnfinalizedDependencies[&DependencyVSO];
|
||||
if (!UnfinalizedDependenciesOnDependencyJD)
|
||||
UnfinalizedDependenciesOnDependencyJD =
|
||||
&DependantMI.UnfinalizedDependencies[&DependencyJD];
|
||||
|
||||
DependencyMI.Dependants[this].insert(DependantName);
|
||||
UnfinalizedDependenciesOnDependencyVSO->insert(DependencyName);
|
||||
UnfinalizedDependenciesOnDependencyJD->insert(DependencyName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VSO &ExecutionSession::createVSO(std::string Name) {
|
||||
return runSessionLocked([&, this]() -> VSO & {
|
||||
VSOs.push_back(std::unique_ptr<VSO>(new VSO(*this, std::move(Name))));
|
||||
return *VSOs.back();
|
||||
JITDylib &ExecutionSession::createJITDylib(std::string Name) {
|
||||
return runSessionLocked([&, this]() -> JITDylib & {
|
||||
JDs.push_back(
|
||||
std::unique_ptr<JITDylib>(new JITDylib(*this, std::move(Name))));
|
||||
return *JDs.back();
|
||||
});
|
||||
}
|
||||
|
||||
Expected<SymbolMap> lookup(const VSOList &VSOs, SymbolNameSet Names) {
|
||||
Expected<SymbolMap> lookup(const JITDylibList &JDs, SymbolNameSet Names) {
|
||||
|
||||
if (VSOs.empty())
|
||||
if (JDs.empty())
|
||||
return SymbolMap();
|
||||
|
||||
auto &ES = (*VSOs.begin())->getExecutionSession();
|
||||
auto &ES = (*JDs.begin())->getExecutionSession();
|
||||
|
||||
return ES.lookup(VSOs, Names, NoDependenciesToRegister, true);
|
||||
return ES.lookup(JDs, Names, NoDependenciesToRegister, true);
|
||||
}
|
||||
|
||||
/// Look up a symbol by searching a list of VSOs.
|
||||
Expected<JITEvaluatedSymbol> lookup(const VSOList &VSOs, SymbolStringPtr Name) {
|
||||
/// Look up a symbol by searching a list of JDs.
|
||||
Expected<JITEvaluatedSymbol> lookup(const JITDylibList &JDs,
|
||||
SymbolStringPtr Name) {
|
||||
SymbolNameSet Names({Name});
|
||||
if (auto ResultMap = lookup(VSOs, std::move(Names))) {
|
||||
if (auto ResultMap = lookup(JDs, std::move(Names))) {
|
||||
assert(ResultMap->size() == 1 && "Unexpected number of results");
|
||||
assert(ResultMap->count(Name) && "Missing result for symbol");
|
||||
return std::move(ResultMap->begin()->second);
|
||||
|
|
|
@ -131,7 +131,7 @@ void CtorDtorRunner2::add(iterator_range<CtorDtorIterator> CtorDtors) {
|
|||
return;
|
||||
|
||||
MangleAndInterner Mangle(
|
||||
V.getExecutionSession(),
|
||||
JD.getExecutionSession(),
|
||||
(*CtorDtors.begin()).Func->getParent()->getDataLayout());
|
||||
|
||||
for (const auto &CtorDtor : CtorDtors) {
|
||||
|
@ -161,7 +161,7 @@ Error CtorDtorRunner2::run() {
|
|||
}
|
||||
}
|
||||
|
||||
if (auto CtorDtorMap = lookup({&V}, std::move(Names))) {
|
||||
if (auto CtorDtorMap = lookup({&JD}, std::move(Names))) {
|
||||
for (auto &KV : CtorDtorsByPriority) {
|
||||
for (auto &Name : KV.second) {
|
||||
assert(CtorDtorMap->count(Name) && "No entry for Name");
|
||||
|
@ -195,7 +195,8 @@ int LocalCXXRuntimeOverridesBase::CXAAtExitOverride(DestructorPtr Destructor,
|
|||
return 0;
|
||||
}
|
||||
|
||||
Error LocalCXXRuntimeOverrides2::enable(VSO &V, MangleAndInterner &Mangle) {
|
||||
Error LocalCXXRuntimeOverrides2::enable(JITDylib &JD,
|
||||
MangleAndInterner &Mangle) {
|
||||
SymbolMap RuntimeInterposes(
|
||||
{{Mangle("__dso_handle"),
|
||||
JITEvaluatedSymbol(toTargetAddress(&DSOHandleOverride),
|
||||
|
@ -204,7 +205,7 @@ Error LocalCXXRuntimeOverrides2::enable(VSO &V, MangleAndInterner &Mangle) {
|
|||
JITEvaluatedSymbol(toTargetAddress(&CXAAtExitOverride),
|
||||
JITSymbolFlags::Exported)}});
|
||||
|
||||
return V.define(absoluteSymbols(std::move(RuntimeInterposes)));
|
||||
return JD.define(absoluteSymbols(std::move(RuntimeInterposes)));
|
||||
}
|
||||
|
||||
DynamicLibraryFallbackGenerator::DynamicLibraryFallbackGenerator(
|
||||
|
@ -213,7 +214,7 @@ DynamicLibraryFallbackGenerator::DynamicLibraryFallbackGenerator(
|
|||
GlobalPrefix(DL.getGlobalPrefix()) {}
|
||||
|
||||
SymbolNameSet DynamicLibraryFallbackGenerator::
|
||||
operator()(VSO &V, const SymbolNameSet &Names) {
|
||||
operator()(JITDylib &JD, const SymbolNameSet &Names) {
|
||||
orc::SymbolNameSet Added;
|
||||
orc::SymbolMap NewSymbols;
|
||||
|
||||
|
@ -235,11 +236,11 @@ operator()(VSO &V, const SymbolNameSet &Names) {
|
|||
}
|
||||
}
|
||||
|
||||
// Add any new symbols to V. Since the fallback generator is only called for
|
||||
// Add any new symbols to JD. Since the fallback generator is only called for
|
||||
// symbols that are not already defined, this will never trigger a duplicate
|
||||
// definition error, so we can wrap this call in a 'cantFail'.
|
||||
if (!NewSymbols.empty())
|
||||
cantFail(V.define(absoluteSymbols(std::move(NewSymbols))));
|
||||
cantFail(JD.define(absoluteSymbols(std::move(NewSymbols))));
|
||||
|
||||
return Added;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ private:
|
|||
R.finalize();
|
||||
}
|
||||
|
||||
void discard(const VSO &V, SymbolStringPtr Name) {
|
||||
void discard(const JITDylib &JD, SymbolStringPtr Name) {
|
||||
llvm_unreachable("Discard should never occur on a LMU?");
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ JITCompileCallbackManager::getCompileCallback(CompileFunction Compile) {
|
|||
|
||||
std::lock_guard<std::mutex> Lock(CCMgrMutex);
|
||||
AddrToSymbol[*TrampolineAddr] = CallbackName;
|
||||
cantFail(CallbacksVSO.define(
|
||||
cantFail(CallbacksJD.define(
|
||||
llvm::make_unique<CompileCallbackMaterializationUnit>(
|
||||
std::move(CallbackName), std::move(Compile))));
|
||||
return *TrampolineAddr;
|
||||
|
@ -97,7 +97,7 @@ JITTargetAddress JITCompileCallbackManager::executeCompileCallback(
|
|||
Name = I->second;
|
||||
}
|
||||
|
||||
if (auto Sym = lookup({&CallbacksVSO}, Name))
|
||||
if (auto Sym = lookup({&CallbacksJD}, Name))
|
||||
return Sym->getAddress();
|
||||
else {
|
||||
// If anything goes wrong materializing Sym then report it to the session
|
||||
|
|
|
@ -28,25 +28,25 @@ Error LLJIT::defineAbsolute(StringRef Name, JITEvaluatedSymbol Sym) {
|
|||
return Main.define(absoluteSymbols(std::move(Symbols)));
|
||||
}
|
||||
|
||||
Error LLJIT::addIRModule(VSO &V, std::unique_ptr<Module> M) {
|
||||
Error LLJIT::addIRModule(JITDylib &JD, std::unique_ptr<Module> M) {
|
||||
assert(M && "Can not add null module");
|
||||
|
||||
if (auto Err = applyDataLayout(*M))
|
||||
return Err;
|
||||
|
||||
auto K = ES->allocateVModule();
|
||||
return CompileLayer.add(V, K, std::move(M));
|
||||
return CompileLayer.add(JD, K, std::move(M));
|
||||
}
|
||||
|
||||
Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(VSO &V,
|
||||
Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD,
|
||||
StringRef Name) {
|
||||
return llvm::orc::lookup({&V}, ES->getSymbolStringPool().intern(Name));
|
||||
return llvm::orc::lookup({&JD}, ES->getSymbolStringPool().intern(Name));
|
||||
}
|
||||
|
||||
LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES,
|
||||
std::unique_ptr<TargetMachine> TM, DataLayout DL)
|
||||
: ES(std::move(ES)), Main(this->ES->createVSO("main")), TM(std::move(TM)),
|
||||
DL(std::move(DL)),
|
||||
: ES(std::move(ES)), Main(this->ES->createJITDylib("main")),
|
||||
TM(std::move(TM)), DL(std::move(DL)),
|
||||
ObjLinkingLayer(*this->ES,
|
||||
[this](VModuleKey K) { return getMemoryManager(K); }),
|
||||
CompileLayer(*this->ES, ObjLinkingLayer, SimpleCompiler(*this->TM)),
|
||||
|
@ -106,7 +106,7 @@ LLLazyJIT::Create(std::unique_ptr<ExecutionSession> ES,
|
|||
std::move(CCMgr), std::move(ISMBuilder)));
|
||||
}
|
||||
|
||||
Error LLLazyJIT::addLazyIRModule(VSO &V, std::unique_ptr<Module> M) {
|
||||
Error LLLazyJIT::addLazyIRModule(JITDylib &JD, std::unique_ptr<Module> M) {
|
||||
assert(M && "Can not add null module");
|
||||
|
||||
if (auto Err = applyDataLayout(*M))
|
||||
|
@ -117,7 +117,7 @@ Error LLLazyJIT::addLazyIRModule(VSO &V, std::unique_ptr<Module> M) {
|
|||
recordCtorDtors(*M);
|
||||
|
||||
auto K = ES->allocateVModule();
|
||||
return CODLayer.add(V, K, std::move(M));
|
||||
return CODLayer.add(JD, K, std::move(M));
|
||||
}
|
||||
|
||||
LLLazyJIT::LLLazyJIT(
|
||||
|
|
|
@ -16,8 +16,8 @@ namespace orc {
|
|||
IRLayer::IRLayer(ExecutionSession &ES) : ES(ES) {}
|
||||
IRLayer::~IRLayer() {}
|
||||
|
||||
Error IRLayer::add(VSO &V, VModuleKey K, std::unique_ptr<Module> M) {
|
||||
return V.define(llvm::make_unique<BasicIRLayerMaterializationUnit>(
|
||||
Error IRLayer::add(JITDylib &JD, VModuleKey K, std::unique_ptr<Module> M) {
|
||||
return JD.define(llvm::make_unique<BasicIRLayerMaterializationUnit>(
|
||||
*this, std::move(K), std::move(M)));
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ IRMaterializationUnit::IRMaterializationUnit(
|
|||
: MaterializationUnit(std::move(SymbolFlags)), M(std::move(M)),
|
||||
SymbolToDefinition(std::move(SymbolToDefinition)) {}
|
||||
|
||||
void IRMaterializationUnit::discard(const VSO &V, SymbolStringPtr Name) {
|
||||
void IRMaterializationUnit::discard(const JITDylib &JD, SymbolStringPtr Name) {
|
||||
auto I = SymbolToDefinition.find(Name);
|
||||
assert(I != SymbolToDefinition.end() &&
|
||||
"Symbol not provided by this MU, or previously discarded");
|
||||
|
@ -66,12 +66,13 @@ ObjectLayer::ObjectLayer(ExecutionSession &ES) : ES(ES) {}
|
|||
|
||||
ObjectLayer::~ObjectLayer() {}
|
||||
|
||||
Error ObjectLayer::add(VSO &V, VModuleKey K, std::unique_ptr<MemoryBuffer> O) {
|
||||
Error ObjectLayer::add(JITDylib &JD, VModuleKey K,
|
||||
std::unique_ptr<MemoryBuffer> O) {
|
||||
auto ObjMU = BasicObjectLayerMaterializationUnit::Create(*this, std::move(K),
|
||||
std::move(O));
|
||||
if (!ObjMU)
|
||||
return ObjMU.takeError();
|
||||
return V.define(std::move(*ObjMU));
|
||||
return JD.define(std::move(*ObjMU));
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<BasicObjectLayerMaterializationUnit>>
|
||||
|
@ -99,7 +100,7 @@ void BasicObjectLayerMaterializationUnit::materialize(
|
|||
L.emit(std::move(R), std::move(K), std::move(O));
|
||||
}
|
||||
|
||||
void BasicObjectLayerMaterializationUnit::discard(const VSO &V,
|
||||
void BasicObjectLayerMaterializationUnit::discard(const JITDylib &JD,
|
||||
SymbolStringPtr Name) {
|
||||
// FIXME: Support object file level discard. This could be done by building a
|
||||
// filter to pass to the object layer along with the object itself.
|
||||
|
|
|
@ -14,12 +14,12 @@ namespace {
|
|||
using namespace llvm;
|
||||
using namespace llvm::orc;
|
||||
|
||||
class VSOSearchOrderResolver : public JITSymbolResolver {
|
||||
class JITDylibSearchOrderResolver : public JITSymbolResolver {
|
||||
public:
|
||||
VSOSearchOrderResolver(MaterializationResponsibility &MR) : MR(MR) {}
|
||||
JITDylibSearchOrderResolver(MaterializationResponsibility &MR) : MR(MR) {}
|
||||
|
||||
Expected<LookupResult> lookup(const LookupSet &Symbols) {
|
||||
auto &ES = MR.getTargetVSO().getExecutionSession();
|
||||
auto &ES = MR.getTargetJITDylib().getExecutionSession();
|
||||
SymbolNameSet InternedSymbols;
|
||||
|
||||
for (auto &S : Symbols)
|
||||
|
@ -30,8 +30,8 @@ public:
|
|||
};
|
||||
|
||||
auto InternedResult =
|
||||
MR.getTargetVSO().withSearchOrderDo([&](const VSOList &VSOs) {
|
||||
return ES.lookup(VSOs, InternedSymbols, RegisterDependencies, false);
|
||||
MR.getTargetJITDylib().withSearchOrderDo([&](const JITDylibList &JDs) {
|
||||
return ES.lookup(JDs, InternedSymbols, RegisterDependencies, false);
|
||||
});
|
||||
|
||||
if (!InternedResult)
|
||||
|
@ -45,7 +45,7 @@ public:
|
|||
}
|
||||
|
||||
Expected<LookupFlagsResult> lookupFlags(const LookupSet &Symbols) {
|
||||
auto &ES = MR.getTargetVSO().getExecutionSession();
|
||||
auto &ES = MR.getTargetJITDylib().getExecutionSession();
|
||||
|
||||
SymbolNameSet InternedSymbols;
|
||||
|
||||
|
@ -53,13 +53,13 @@ public:
|
|||
InternedSymbols.insert(ES.getSymbolStringPool().intern(S));
|
||||
|
||||
SymbolFlagsMap InternedResult;
|
||||
MR.getTargetVSO().withSearchOrderDo([&](const VSOList &VSOs) {
|
||||
MR.getTargetJITDylib().withSearchOrderDo([&](const JITDylibList &JDs) {
|
||||
// An empty search order is pathalogical, but allowed.
|
||||
if (VSOs.empty())
|
||||
if (JDs.empty())
|
||||
return;
|
||||
|
||||
assert(VSOs.front() && "VSOList entry can not be null");
|
||||
InternedResult = VSOs.front()->lookupFlags(InternedSymbols);
|
||||
assert(JDs.front() && "VSOList entry can not be null");
|
||||
InternedResult = JDs.front()->lookupFlags(InternedSymbols);
|
||||
});
|
||||
|
||||
LookupFlagsResult Result;
|
||||
|
@ -100,7 +100,7 @@ void RTDyldObjectLinkingLayer2::emit(MaterializationResponsibility R,
|
|||
|
||||
auto MemoryManager = GetMemoryManager(K);
|
||||
|
||||
VSOSearchOrderResolver Resolver(R);
|
||||
JITDylibSearchOrderResolver Resolver(R);
|
||||
auto RTDyld = llvm::make_unique<RuntimeDyld>(*MemoryManager, Resolver);
|
||||
RTDyld->setProcessAllSections(ProcessAllSections);
|
||||
|
||||
|
|
|
@ -781,13 +781,13 @@ int runOrcLazyJIT(LLVMContext &Ctx, std::vector<std::unique_ptr<Module>> Ms,
|
|||
}
|
||||
return Dump(std::move(M));
|
||||
});
|
||||
J->getMainVSO().setFallbackDefinitionGenerator(
|
||||
J->getMainJITDylib().setFallbackDefinitionGenerator(
|
||||
orc::DynamicLibraryFallbackGenerator(
|
||||
std::move(LibLLI), DL, [](orc::SymbolStringPtr) { return true; }));
|
||||
|
||||
orc::MangleAndInterner Mangle(J->getExecutionSession(), DL);
|
||||
orc::LocalCXXRuntimeOverrides2 CXXRuntimeOverrides;
|
||||
ExitOnErr(CXXRuntimeOverrides.enable(J->getMainVSO(), Mangle));
|
||||
ExitOnErr(CXXRuntimeOverrides.enable(J->getMainJITDylib(), Mangle));
|
||||
|
||||
for (auto &M : Ms) {
|
||||
orc::makeAllSymbolsExternallyAccessible(*M);
|
||||
|
|
|
@ -26,7 +26,8 @@ class SimpleMaterializationUnit : public MaterializationUnit {
|
|||
public:
|
||||
using MaterializeFunction =
|
||||
std::function<void(MaterializationResponsibility)>;
|
||||
using DiscardFunction = std::function<void(const VSO &, SymbolStringPtr)>;
|
||||
using DiscardFunction =
|
||||
std::function<void(const JITDylib &, SymbolStringPtr)>;
|
||||
using DestructorFunction = std::function<void()>;
|
||||
|
||||
SimpleMaterializationUnit(
|
||||
|
@ -46,9 +47,9 @@ public:
|
|||
Materialize(std::move(R));
|
||||
}
|
||||
|
||||
void discard(const VSO &V, SymbolStringPtr Name) override {
|
||||
void discard(const JITDylib &JD, SymbolStringPtr Name) override {
|
||||
if (Discard)
|
||||
Discard(V, std::move(Name));
|
||||
Discard(JD, std::move(Name));
|
||||
else
|
||||
llvm_unreachable("Discard not supported");
|
||||
}
|
||||
|
@ -79,13 +80,13 @@ TEST_F(CoreAPIsStandardTest, BasicSuccessfulLookup) {
|
|||
|
||||
std::shared_ptr<MaterializationResponsibility> FooMR;
|
||||
|
||||
cantFail(V.define(llvm::make_unique<SimpleMaterializationUnit>(
|
||||
cantFail(JD.define(llvm::make_unique<SimpleMaterializationUnit>(
|
||||
SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
|
||||
[&](MaterializationResponsibility R) {
|
||||
FooMR = std::make_shared<MaterializationResponsibility>(std::move(R));
|
||||
})));
|
||||
|
||||
ES.lookup({&V}, {Foo}, OnResolution, OnReady, NoDependenciesToRegister);
|
||||
ES.lookup({&JD}, {Foo}, OnResolution, OnReady, NoDependenciesToRegister);
|
||||
|
||||
EXPECT_FALSE(OnResolutionRun) << "Should not have been resolved yet";
|
||||
EXPECT_FALSE(OnReadyRun) << "Should not have been marked ready yet";
|
||||
|
@ -138,16 +139,16 @@ TEST_F(CoreAPIsStandardTest, EmptyLookup) {
|
|||
OnReadyRun = true;
|
||||
};
|
||||
|
||||
ES.lookup({&V}, {}, OnResolution, OnReady, NoDependenciesToRegister);
|
||||
ES.lookup({&JD}, {}, OnResolution, OnReady, NoDependenciesToRegister);
|
||||
|
||||
EXPECT_TRUE(OnResolvedRun) << "OnResolved was not run for empty query";
|
||||
EXPECT_TRUE(OnReadyRun) << "OnReady was not run for empty query";
|
||||
}
|
||||
|
||||
TEST_F(CoreAPIsStandardTest, ChainedVSOLookup) {
|
||||
cantFail(V.define(absoluteSymbols({{Foo, FooSym}})));
|
||||
TEST_F(CoreAPIsStandardTest, ChainedJITDylibLookup) {
|
||||
cantFail(JD.define(absoluteSymbols({{Foo, FooSym}})));
|
||||
|
||||
auto &V2 = ES.createVSO("V2");
|
||||
auto &JD2 = ES.createJITDylib("JD2");
|
||||
|
||||
bool OnResolvedRun = false;
|
||||
bool OnReadyRun = false;
|
||||
|
@ -163,7 +164,7 @@ TEST_F(CoreAPIsStandardTest, ChainedVSOLookup) {
|
|||
OnReadyRun = true;
|
||||
});
|
||||
|
||||
V2.legacyLookup(Q, V.legacyLookup(Q, {Foo}));
|
||||
JD2.legacyLookup(Q, JD.legacyLookup(Q, {Foo}));
|
||||
|
||||
EXPECT_TRUE(OnResolvedRun) << "OnResolved was not run for empty query";
|
||||
EXPECT_TRUE(OnReadyRun) << "OnReady was not run for empty query";
|
||||
|
@ -182,12 +183,12 @@ TEST_F(CoreAPIsStandardTest, LookupFlagsTest) {
|
|||
llvm_unreachable("Symbol materialized on flags lookup");
|
||||
});
|
||||
|
||||
cantFail(V.define(absoluteSymbols({{Foo, FooSym}})));
|
||||
cantFail(V.define(std::move(MU)));
|
||||
cantFail(JD.define(absoluteSymbols({{Foo, FooSym}})));
|
||||
cantFail(JD.define(std::move(MU)));
|
||||
|
||||
SymbolNameSet Names({Foo, Bar, Baz});
|
||||
|
||||
auto SymbolFlags = V.lookupFlags(Names);
|
||||
auto SymbolFlags = JD.lookupFlags(Names);
|
||||
|
||||
EXPECT_EQ(SymbolFlags.size(), 2U)
|
||||
<< "Returned symbol flags contains unexpected results";
|
||||
|
@ -201,12 +202,12 @@ TEST_F(CoreAPIsStandardTest, LookupFlagsTest) {
|
|||
}
|
||||
|
||||
TEST_F(CoreAPIsStandardTest, TestBasicAliases) {
|
||||
cantFail(V.define(absoluteSymbols({{Foo, FooSym}, {Bar, BarSym}})));
|
||||
cantFail(V.define(symbolAliases({{Baz, {Foo, JITSymbolFlags::Exported}},
|
||||
{Qux, {Bar, JITSymbolFlags::Weak}}})));
|
||||
cantFail(V.define(absoluteSymbols({{Qux, QuxSym}})));
|
||||
cantFail(JD.define(absoluteSymbols({{Foo, FooSym}, {Bar, BarSym}})));
|
||||
cantFail(JD.define(symbolAliases({{Baz, {Foo, JITSymbolFlags::Exported}},
|
||||
{Qux, {Bar, JITSymbolFlags::Weak}}})));
|
||||
cantFail(JD.define(absoluteSymbols({{Qux, QuxSym}})));
|
||||
|
||||
auto Result = lookup({&V}, {Baz, Qux});
|
||||
auto Result = lookup({&JD}, {Baz, Qux});
|
||||
EXPECT_TRUE(!!Result) << "Unexpected lookup failure";
|
||||
EXPECT_EQ(Result->count(Baz), 1U) << "No result for \"baz\"";
|
||||
EXPECT_EQ(Result->count(Qux), 1U) << "No result for \"qux\"";
|
||||
|
@ -217,11 +218,11 @@ TEST_F(CoreAPIsStandardTest, TestBasicAliases) {
|
|||
}
|
||||
|
||||
TEST_F(CoreAPIsStandardTest, TestChainedAliases) {
|
||||
cantFail(V.define(absoluteSymbols({{Foo, FooSym}})));
|
||||
cantFail(V.define(symbolAliases(
|
||||
cantFail(JD.define(absoluteSymbols({{Foo, FooSym}})));
|
||||
cantFail(JD.define(symbolAliases(
|
||||
{{Baz, {Bar, BazSym.getFlags()}}, {Bar, {Foo, BarSym.getFlags()}}})));
|
||||
|
||||
auto Result = lookup({&V}, {Bar, Baz});
|
||||
auto Result = lookup({&JD}, {Bar, Baz});
|
||||
EXPECT_TRUE(!!Result) << "Unexpected lookup failure";
|
||||
EXPECT_EQ(Result->count(Bar), 1U) << "No result for \"bar\"";
|
||||
EXPECT_EQ(Result->count(Baz), 1U) << "No result for \"baz\"";
|
||||
|
@ -233,14 +234,14 @@ TEST_F(CoreAPIsStandardTest, TestChainedAliases) {
|
|||
|
||||
TEST_F(CoreAPIsStandardTest, TestBasicReExports) {
|
||||
// Test that the basic use case of re-exporting a single symbol from another
|
||||
// VSO works.
|
||||
cantFail(V.define(absoluteSymbols({{Foo, FooSym}})));
|
||||
// JITDylib works.
|
||||
cantFail(JD.define(absoluteSymbols({{Foo, FooSym}})));
|
||||
|
||||
auto &V2 = ES.createVSO("V2");
|
||||
auto &JD2 = ES.createJITDylib("JD2");
|
||||
|
||||
cantFail(V2.define(reexports(V, {{Bar, {Foo, BarSym.getFlags()}}})));
|
||||
cantFail(JD2.define(reexports(JD, {{Bar, {Foo, BarSym.getFlags()}}})));
|
||||
|
||||
auto Result = cantFail(lookup({&V2}, Bar));
|
||||
auto Result = cantFail(lookup({&JD2}, Bar));
|
||||
EXPECT_EQ(Result.getAddress(), FooSym.getAddress())
|
||||
<< "Re-export Bar for symbol Foo should match FooSym's address";
|
||||
}
|
||||
|
@ -248,7 +249,7 @@ TEST_F(CoreAPIsStandardTest, TestBasicReExports) {
|
|||
TEST_F(CoreAPIsStandardTest, TestThatReExportsDontUnnecessarilyMaterialize) {
|
||||
// Test that re-exports do not materialize symbols that have not been queried
|
||||
// for.
|
||||
cantFail(V.define(absoluteSymbols({{Foo, FooSym}})));
|
||||
cantFail(JD.define(absoluteSymbols({{Foo, FooSym}})));
|
||||
|
||||
bool BarMaterialized = false;
|
||||
auto BarMU = llvm::make_unique<SimpleMaterializationUnit>(
|
||||
|
@ -259,14 +260,14 @@ TEST_F(CoreAPIsStandardTest, TestThatReExportsDontUnnecessarilyMaterialize) {
|
|||
R.finalize();
|
||||
});
|
||||
|
||||
cantFail(V.define(BarMU));
|
||||
cantFail(JD.define(BarMU));
|
||||
|
||||
auto &V2 = ES.createVSO("V2");
|
||||
auto &JD2 = ES.createJITDylib("JD2");
|
||||
|
||||
cantFail(V2.define(reexports(
|
||||
V, {{Baz, {Foo, BazSym.getFlags()}}, {Qux, {Bar, QuxSym.getFlags()}}})));
|
||||
cantFail(JD2.define(reexports(
|
||||
JD, {{Baz, {Foo, BazSym.getFlags()}}, {Qux, {Bar, QuxSym.getFlags()}}})));
|
||||
|
||||
auto Result = cantFail(lookup({&V2}, Baz));
|
||||
auto Result = cantFail(lookup({&JD2}, Baz));
|
||||
EXPECT_EQ(Result.getAddress(), FooSym.getAddress())
|
||||
<< "Re-export Baz for symbol Foo should match FooSym's address";
|
||||
|
||||
|
@ -277,19 +278,19 @@ TEST_F(CoreAPIsStandardTest, TestReexportsFallbackGenerator) {
|
|||
// Test that a re-exports fallback generator can dynamically generate
|
||||
// reexports.
|
||||
|
||||
auto &V2 = ES.createVSO("V2");
|
||||
cantFail(V2.define(absoluteSymbols({{Foo, FooSym}, {Bar, BarSym}})));
|
||||
auto &JD2 = ES.createJITDylib("JD2");
|
||||
cantFail(JD2.define(absoluteSymbols({{Foo, FooSym}, {Bar, BarSym}})));
|
||||
|
||||
auto Filter = [this](SymbolStringPtr Name) { return Name != Bar; };
|
||||
|
||||
V.setFallbackDefinitionGenerator(
|
||||
ReexportsFallbackDefinitionGenerator(V2, Filter));
|
||||
JD.setFallbackDefinitionGenerator(
|
||||
ReexportsFallbackDefinitionGenerator(JD2, Filter));
|
||||
|
||||
auto Flags = V.lookupFlags({Foo, Bar, Baz});
|
||||
auto Flags = JD.lookupFlags({Foo, Bar, Baz});
|
||||
EXPECT_EQ(Flags.size(), 1U) << "Unexpected number of results";
|
||||
EXPECT_EQ(Flags[Foo], FooSym.getFlags()) << "Unexpected flags for Foo";
|
||||
|
||||
auto Result = cantFail(lookup({&V}, Foo));
|
||||
auto Result = cantFail(lookup({&JD}, Foo));
|
||||
|
||||
EXPECT_EQ(Result.getAddress(), FooSym.getAddress())
|
||||
<< "Incorrect reexported symbol address";
|
||||
|
@ -301,7 +302,7 @@ TEST_F(CoreAPIsStandardTest, TestTrivialCircularDependency) {
|
|||
SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
|
||||
[&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); });
|
||||
|
||||
cantFail(V.define(FooMU));
|
||||
cantFail(JD.define(FooMU));
|
||||
|
||||
bool FooReady = false;
|
||||
auto OnResolution = [](Expected<SymbolMap> R) { cantFail(std::move(R)); };
|
||||
|
@ -310,7 +311,7 @@ TEST_F(CoreAPIsStandardTest, TestTrivialCircularDependency) {
|
|||
FooReady = true;
|
||||
};
|
||||
|
||||
ES.lookup({&V}, {Foo}, std::move(OnResolution), std::move(OnReady),
|
||||
ES.lookup({&JD}, {Foo}, std::move(OnResolution), std::move(OnReady),
|
||||
NoDependenciesToRegister);
|
||||
|
||||
FooR->resolve({{Foo, FooSym}});
|
||||
|
@ -320,9 +321,9 @@ TEST_F(CoreAPIsStandardTest, TestTrivialCircularDependency) {
|
|||
<< "Self-dependency prevented symbol from being marked ready";
|
||||
}
|
||||
|
||||
TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneVSO) {
|
||||
// Test that a circular symbol dependency between three symbols in a VSO does
|
||||
// not prevent any symbol from becoming 'ready' once all symbols are
|
||||
TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneJITDylib) {
|
||||
// Test that a circular symbol dependency between three symbols in a JITDylib
|
||||
// does not prevent any symbol from becoming 'ready' once all symbols are
|
||||
// finalized.
|
||||
|
||||
// Create three MaterializationResponsibility objects: one for each of Foo,
|
||||
|
@ -347,9 +348,9 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneVSO) {
|
|||
[&](MaterializationResponsibility R) { BazR.emplace(std::move(R)); });
|
||||
|
||||
// Define the symbols.
|
||||
cantFail(V.define(FooMU));
|
||||
cantFail(V.define(BarMU));
|
||||
cantFail(V.define(BazMU));
|
||||
cantFail(JD.define(FooMU));
|
||||
cantFail(JD.define(BarMU));
|
||||
cantFail(JD.define(BazMU));
|
||||
|
||||
// Query each of the symbols to trigger materialization.
|
||||
bool FooResolved = false;
|
||||
|
@ -367,7 +368,7 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneVSO) {
|
|||
|
||||
// Issue a lookup for Foo. Use NoDependenciesToRegister: We're going to add
|
||||
// the dependencies manually below.
|
||||
ES.lookup({&V}, {Foo}, std::move(OnFooResolution), std::move(OnFooReady),
|
||||
ES.lookup({&JD}, {Foo}, std::move(OnFooResolution), std::move(OnFooReady),
|
||||
NoDependenciesToRegister);
|
||||
|
||||
bool BarResolved = false;
|
||||
|
@ -382,7 +383,7 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneVSO) {
|
|||
BarReady = true;
|
||||
};
|
||||
|
||||
ES.lookup({&V}, {Bar}, std::move(OnBarResolution), std::move(OnBarReady),
|
||||
ES.lookup({&JD}, {Bar}, std::move(OnBarResolution), std::move(OnBarReady),
|
||||
NoDependenciesToRegister);
|
||||
|
||||
bool BazResolved = false;
|
||||
|
@ -398,19 +399,19 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneVSO) {
|
|||
BazReady = true;
|
||||
};
|
||||
|
||||
ES.lookup({&V}, {Baz}, std::move(OnBazResolution), std::move(OnBazReady),
|
||||
ES.lookup({&JD}, {Baz}, std::move(OnBazResolution), std::move(OnBazReady),
|
||||
NoDependenciesToRegister);
|
||||
|
||||
// Add a circular dependency: Foo -> Bar, Bar -> Baz, Baz -> Foo.
|
||||
FooR->addDependenciesForAll({{&V, SymbolNameSet({Bar})}});
|
||||
BarR->addDependenciesForAll({{&V, SymbolNameSet({Baz})}});
|
||||
BazR->addDependenciesForAll({{&V, SymbolNameSet({Foo})}});
|
||||
FooR->addDependenciesForAll({{&JD, SymbolNameSet({Bar})}});
|
||||
BarR->addDependenciesForAll({{&JD, SymbolNameSet({Baz})}});
|
||||
BazR->addDependenciesForAll({{&JD, SymbolNameSet({Foo})}});
|
||||
|
||||
// Add self-dependencies for good measure. This tests that the implementation
|
||||
// of addDependencies filters these out.
|
||||
FooR->addDependenciesForAll({{&V, SymbolNameSet({Foo})}});
|
||||
BarR->addDependenciesForAll({{&V, SymbolNameSet({Bar})}});
|
||||
BazR->addDependenciesForAll({{&V, SymbolNameSet({Baz})}});
|
||||
FooR->addDependenciesForAll({{&JD, SymbolNameSet({Foo})}});
|
||||
BarR->addDependenciesForAll({{&JD, SymbolNameSet({Bar})}});
|
||||
BazR->addDependenciesForAll({{&JD, SymbolNameSet({Baz})}});
|
||||
|
||||
// Check that nothing has been resolved yet.
|
||||
EXPECT_FALSE(FooResolved) << "\"Foo\" should not be resolved yet";
|
||||
|
@ -460,20 +461,20 @@ TEST_F(CoreAPIsStandardTest, DropMaterializerWhenEmpty) {
|
|||
[](MaterializationResponsibility R) {
|
||||
llvm_unreachable("Unexpected call to materialize");
|
||||
},
|
||||
[&](const VSO &V, SymbolStringPtr Name) {
|
||||
[&](const JITDylib &JD, SymbolStringPtr Name) {
|
||||
EXPECT_TRUE(Name == Foo || Name == Bar)
|
||||
<< "Discard of unexpected symbol?";
|
||||
},
|
||||
[&]() { DestructorRun = true; });
|
||||
|
||||
cantFail(V.define(MU));
|
||||
cantFail(JD.define(MU));
|
||||
|
||||
cantFail(V.define(absoluteSymbols({{Foo, FooSym}})));
|
||||
cantFail(JD.define(absoluteSymbols({{Foo, FooSym}})));
|
||||
|
||||
EXPECT_FALSE(DestructorRun)
|
||||
<< "MaterializationUnit should not have been destroyed yet";
|
||||
|
||||
cantFail(V.define(absoluteSymbols({{Bar, BarSym}})));
|
||||
cantFail(JD.define(absoluteSymbols({{Bar, BarSym}})));
|
||||
|
||||
EXPECT_TRUE(DestructorRun)
|
||||
<< "MaterializationUnit should have been destroyed";
|
||||
|
@ -494,13 +495,13 @@ TEST_F(CoreAPIsStandardTest, AddAndMaterializeLazySymbol) {
|
|||
R.finalize();
|
||||
FooMaterialized = true;
|
||||
},
|
||||
[&](const VSO &V, SymbolStringPtr Name) {
|
||||
[&](const JITDylib &JD, SymbolStringPtr Name) {
|
||||
EXPECT_EQ(Name, Bar) << "Expected Name to be Bar";
|
||||
BarDiscarded = true;
|
||||
});
|
||||
|
||||
cantFail(V.define(MU));
|
||||
cantFail(V.define(absoluteSymbols({{Bar, BarSym}})));
|
||||
cantFail(JD.define(MU));
|
||||
cantFail(JD.define(absoluteSymbols({{Bar, BarSym}})));
|
||||
|
||||
SymbolNameSet Names({Foo});
|
||||
|
||||
|
@ -521,7 +522,7 @@ TEST_F(CoreAPIsStandardTest, AddAndMaterializeLazySymbol) {
|
|||
OnReadyRun = true;
|
||||
};
|
||||
|
||||
ES.lookup({&V}, Names, std::move(OnResolution), std::move(OnReady),
|
||||
ES.lookup({&JD}, Names, std::move(OnResolution), std::move(OnReady),
|
||||
NoDependenciesToRegister);
|
||||
|
||||
EXPECT_TRUE(FooMaterialized) << "Foo was not materialized";
|
||||
|
@ -533,10 +534,10 @@ TEST_F(CoreAPIsStandardTest, AddAndMaterializeLazySymbol) {
|
|||
TEST_F(CoreAPIsStandardTest, DefineMaterializingSymbol) {
|
||||
bool ExpectNoMoreMaterialization = false;
|
||||
ES.setDispatchMaterialization(
|
||||
[&](VSO &V, std::unique_ptr<MaterializationUnit> MU) {
|
||||
[&](JITDylib &JD, std::unique_ptr<MaterializationUnit> MU) {
|
||||
if (ExpectNoMoreMaterialization)
|
||||
ADD_FAILURE() << "Unexpected materialization";
|
||||
MU->doMaterialize(V);
|
||||
MU->doMaterialize(JD);
|
||||
});
|
||||
|
||||
auto MU = llvm::make_unique<SimpleMaterializationUnit>(
|
||||
|
@ -548,27 +549,28 @@ TEST_F(CoreAPIsStandardTest, DefineMaterializingSymbol) {
|
|||
R.finalize();
|
||||
});
|
||||
|
||||
cantFail(V.define(MU));
|
||||
cantFail(lookup({&V}, Foo));
|
||||
cantFail(JD.define(MU));
|
||||
cantFail(lookup({&JD}, Foo));
|
||||
|
||||
// Assert that materialization is complete by now.
|
||||
ExpectNoMoreMaterialization = true;
|
||||
|
||||
// Look up bar to verify that no further materialization happens.
|
||||
auto BarResult = cantFail(lookup({&V}, Bar));
|
||||
auto BarResult = cantFail(lookup({&JD}, Bar));
|
||||
EXPECT_EQ(BarResult.getAddress(), BarSym.getAddress())
|
||||
<< "Expected Bar == BarSym";
|
||||
}
|
||||
|
||||
TEST_F(CoreAPIsStandardTest, FallbackDefinitionGeneratorTest) {
|
||||
cantFail(V.define(absoluteSymbols({{Foo, FooSym}})));
|
||||
cantFail(JD.define(absoluteSymbols({{Foo, FooSym}})));
|
||||
|
||||
V.setFallbackDefinitionGenerator([&](VSO &W, const SymbolNameSet &Names) {
|
||||
cantFail(W.define(absoluteSymbols({{Bar, BarSym}})));
|
||||
return SymbolNameSet({Bar});
|
||||
});
|
||||
JD.setFallbackDefinitionGenerator(
|
||||
[&](JITDylib &JD2, const SymbolNameSet &Names) {
|
||||
cantFail(JD2.define(absoluteSymbols({{Bar, BarSym}})));
|
||||
return SymbolNameSet({Bar});
|
||||
});
|
||||
|
||||
auto Result = cantFail(lookup({&V}, {Foo, Bar}));
|
||||
auto Result = cantFail(lookup({&JD}, {Foo, Bar}));
|
||||
|
||||
EXPECT_EQ(Result.count(Bar), 1U) << "Expected to find fallback def for 'bar'";
|
||||
EXPECT_EQ(Result[Bar].getAddress(), BarSym.getAddress())
|
||||
|
@ -581,10 +583,10 @@ TEST_F(CoreAPIsStandardTest, FailResolution) {
|
|||
{{Foo, JITSymbolFlags::Weak}, {Bar, JITSymbolFlags::Weak}}),
|
||||
[&](MaterializationResponsibility R) { R.failMaterialization(); });
|
||||
|
||||
cantFail(V.define(MU));
|
||||
cantFail(JD.define(MU));
|
||||
|
||||
SymbolNameSet Names({Foo, Bar});
|
||||
auto Result = lookup({&V}, Names);
|
||||
auto Result = lookup({&JD}, Names);
|
||||
|
||||
EXPECT_FALSE(!!Result) << "Expected failure";
|
||||
if (!Result) {
|
||||
|
@ -614,9 +616,9 @@ TEST_F(CoreAPIsStandardTest, TestLookupWithUnthreadedMaterialization) {
|
|||
R.finalize();
|
||||
});
|
||||
|
||||
cantFail(V.define(MU));
|
||||
cantFail(JD.define(MU));
|
||||
|
||||
auto FooLookupResult = cantFail(lookup({&V}, Foo));
|
||||
auto FooLookupResult = cantFail(lookup({&JD}, Foo));
|
||||
|
||||
EXPECT_EQ(FooLookupResult.getAddress(), FooSym.getAddress())
|
||||
<< "lookup returned an incorrect address";
|
||||
|
@ -629,15 +631,15 @@ TEST_F(CoreAPIsStandardTest, TestLookupWithThreadedMaterialization) {
|
|||
|
||||
std::thread MaterializationThread;
|
||||
ES.setDispatchMaterialization(
|
||||
[&](VSO &V, std::unique_ptr<MaterializationUnit> MU) {
|
||||
[&](JITDylib &JD, std::unique_ptr<MaterializationUnit> MU) {
|
||||
auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU));
|
||||
MaterializationThread =
|
||||
std::thread([SharedMU, &V]() { SharedMU->doMaterialize(V); });
|
||||
std::thread([SharedMU, &JD]() { SharedMU->doMaterialize(JD); });
|
||||
});
|
||||
|
||||
cantFail(V.define(absoluteSymbols({{Foo, FooSym}})));
|
||||
cantFail(JD.define(absoluteSymbols({{Foo, FooSym}})));
|
||||
|
||||
auto FooLookupResult = cantFail(lookup({&V}, Foo));
|
||||
auto FooLookupResult = cantFail(lookup({&JD}, Foo));
|
||||
|
||||
EXPECT_EQ(FooLookupResult.getAddress(), FooSym.getAddress())
|
||||
<< "lookup returned an incorrect address";
|
||||
|
@ -650,7 +652,7 @@ TEST_F(CoreAPIsStandardTest, TestLookupWithThreadedMaterialization) {
|
|||
TEST_F(CoreAPIsStandardTest, TestGetRequestedSymbolsAndReplace) {
|
||||
// Test that GetRequestedSymbols returns the set of symbols that currently
|
||||
// have pending queries, and test that MaterializationResponsibility's
|
||||
// replace method can be used to return definitions to the VSO in a new
|
||||
// replace method can be used to return definitions to the JITDylib in a new
|
||||
// MaterializationUnit.
|
||||
SymbolNameSet Names({Foo, Bar});
|
||||
|
||||
|
@ -680,19 +682,19 @@ TEST_F(CoreAPIsStandardTest, TestGetRequestedSymbolsAndReplace) {
|
|||
FooMaterialized = true;
|
||||
});
|
||||
|
||||
cantFail(V.define(MU));
|
||||
cantFail(JD.define(MU));
|
||||
|
||||
EXPECT_FALSE(FooMaterialized) << "Foo should not be materialized yet";
|
||||
EXPECT_FALSE(BarMaterialized) << "Bar should not be materialized yet";
|
||||
|
||||
auto FooSymResult = cantFail(lookup({&V}, Foo));
|
||||
auto FooSymResult = cantFail(lookup({&JD}, Foo));
|
||||
EXPECT_EQ(FooSymResult.getAddress(), FooSym.getAddress())
|
||||
<< "Address mismatch for Foo";
|
||||
|
||||
EXPECT_TRUE(FooMaterialized) << "Foo should be materialized now";
|
||||
EXPECT_FALSE(BarMaterialized) << "Bar still should not be materialized";
|
||||
|
||||
auto BarSymResult = cantFail(lookup({&V}, Bar));
|
||||
auto BarSymResult = cantFail(lookup({&JD}, Bar));
|
||||
EXPECT_EQ(BarSymResult.getAddress(), BarSym.getAddress())
|
||||
<< "Address mismatch for Bar";
|
||||
EXPECT_TRUE(BarMaterialized) << "Bar should be materialized now";
|
||||
|
@ -710,9 +712,9 @@ TEST_F(CoreAPIsStandardTest, TestMaterializationResponsibilityDelegation) {
|
|||
R2.finalize();
|
||||
});
|
||||
|
||||
cantFail(V.define(MU));
|
||||
cantFail(JD.define(MU));
|
||||
|
||||
auto Result = lookup({&V}, {Foo, Bar});
|
||||
auto Result = lookup({&JD}, {Foo, Bar});
|
||||
|
||||
EXPECT_TRUE(!!Result) << "Result should be a success value";
|
||||
EXPECT_EQ(Result->count(Foo), 1U) << "\"Foo\" entry missing";
|
||||
|
@ -737,14 +739,14 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) {
|
|||
llvm::make_unique<MaterializationResponsibility>(std::move(R));
|
||||
});
|
||||
|
||||
cantFail(V.define(MU));
|
||||
cantFail(JD.define(MU));
|
||||
auto OnResolution = [](Expected<SymbolMap> Result) {
|
||||
cantFail(std::move(Result));
|
||||
};
|
||||
|
||||
auto OnReady = [](Error Err) { cantFail(std::move(Err)); };
|
||||
|
||||
ES.lookup({&V}, {Foo}, std::move(OnResolution), std::move(OnReady),
|
||||
ES.lookup({&JD}, {Foo}, std::move(OnResolution), std::move(OnReady),
|
||||
NoDependenciesToRegister);
|
||||
|
||||
auto MU2 = llvm::make_unique<SimpleMaterializationUnit>(
|
||||
|
@ -753,7 +755,7 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) {
|
|||
llvm_unreachable("This unit should never be materialized");
|
||||
});
|
||||
|
||||
auto Err = V.define(MU2);
|
||||
auto Err = JD.define(MU2);
|
||||
EXPECT_TRUE(!!Err) << "Expected failure value";
|
||||
EXPECT_TRUE(Err.isA<DuplicateDefinition>())
|
||||
<< "Expected a duplicate definition error";
|
||||
|
|
|
@ -19,12 +19,12 @@ class LegacyAPIsStandardTest : public CoreAPIsBasedStandardTest {};
|
|||
namespace {
|
||||
|
||||
TEST_F(LegacyAPIsStandardTest, TestLambdaSymbolResolver) {
|
||||
cantFail(V.define(absoluteSymbols({{Foo, FooSym}, {Bar, BarSym}})));
|
||||
cantFail(JD.define(absoluteSymbols({{Foo, FooSym}, {Bar, BarSym}})));
|
||||
|
||||
auto Resolver = createSymbolResolver(
|
||||
[&](const SymbolNameSet &Symbols) { return V.lookupFlags(Symbols); },
|
||||
[&](const SymbolNameSet &Symbols) { return JD.lookupFlags(Symbols); },
|
||||
[&](std::shared_ptr<AsynchronousSymbolQuery> Q, SymbolNameSet Symbols) {
|
||||
return V.legacyLookup(std::move(Q), Symbols);
|
||||
return JD.legacyLookup(std::move(Q), Symbols);
|
||||
});
|
||||
|
||||
SymbolNameSet Symbols({Foo, Bar, Baz});
|
||||
|
@ -66,22 +66,22 @@ TEST_F(LegacyAPIsStandardTest, TestLambdaSymbolResolver) {
|
|||
EXPECT_TRUE(OnResolvedRun) << "OnResolved was never run";
|
||||
}
|
||||
|
||||
TEST(LegacyAPIInteropTest, QueryAgainstVSO) {
|
||||
TEST(LegacyAPIInteropTest, QueryAgainstJITDylib) {
|
||||
|
||||
ExecutionSession ES(std::make_shared<SymbolStringPool>());
|
||||
auto Foo = ES.getSymbolStringPool().intern("foo");
|
||||
|
||||
auto &V = ES.createVSO("V");
|
||||
auto &JD = ES.createJITDylib("JD");
|
||||
JITEvaluatedSymbol FooSym(0xdeadbeef, JITSymbolFlags::Exported);
|
||||
cantFail(V.define(absoluteSymbols({{Foo, FooSym}})));
|
||||
cantFail(JD.define(absoluteSymbols({{Foo, FooSym}})));
|
||||
|
||||
auto LookupFlags = [&](const SymbolNameSet &Names) {
|
||||
return V.lookupFlags(Names);
|
||||
return JD.lookupFlags(Names);
|
||||
};
|
||||
|
||||
auto Lookup = [&](std::shared_ptr<AsynchronousSymbolQuery> Query,
|
||||
SymbolNameSet Symbols) {
|
||||
return V.legacyLookup(std::move(Query), Symbols);
|
||||
return JD.legacyLookup(std::move(Query), Symbols);
|
||||
};
|
||||
|
||||
auto UnderlyingResolver =
|
||||
|
|
|
@ -44,12 +44,12 @@ namespace orc {
|
|||
// (4) FooSym, BarSym, BazSym, QuxSym -- JITEvaluatedSymbols with FooAddr,
|
||||
// BarAddr, BazAddr, and QuxAddr respectively. All with default strong,
|
||||
// linkage and non-hidden visibility.
|
||||
// (5) V -- A VSO associated with ES.
|
||||
// (5) V -- A JITDylib associated with ES.
|
||||
class CoreAPIsBasedStandardTest : public testing::Test {
|
||||
public:
|
||||
protected:
|
||||
ExecutionSession ES;
|
||||
VSO &V = ES.createVSO("V");
|
||||
JITDylib &JD = ES.createJITDylib("JD");
|
||||
SymbolStringPtr Foo = ES.getSymbolStringPool().intern("foo");
|
||||
SymbolStringPtr Bar = ES.getSymbolStringPool().intern("bar");
|
||||
SymbolStringPtr Baz = ES.getSymbolStringPool().intern("baz");
|
||||
|
|
Loading…
Reference in New Issue