Update prebuilt Clang to r365631c1 from Android.
The version we had was segfaulting.
Bug: 132420445
Change-Id: Icb45a6fe0b4e2166f7895e669df1157cec9fb4e0
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/CompileUtils.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/CompileUtils.h
index 15a6566..1585925 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/CompileUtils.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/CompileUtils.h
@@ -13,25 +13,17 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H
#define LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
-#include "llvm/IR/LegacyPassManager.h"
-#include "llvm/Object/Binary.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/SmallVectorMemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetMachine.h"
-#include <algorithm>
#include <memory>
namespace llvm {
+class JITTargetMachineBuilder;
class MCContext;
+class MemoryBuffer;
class Module;
+class ObjectCache;
+class TargetMachine;
namespace orc {
@@ -50,51 +42,11 @@
void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; }
/// Compile a Module to an ObjectFile.
- CompileResult operator()(Module &M) {
- CompileResult CachedObject = tryToLoadFromObjectCache(M);
- if (CachedObject)
- return CachedObject;
-
- SmallVector<char, 0> ObjBufferSV;
-
- {
- raw_svector_ostream ObjStream(ObjBufferSV);
-
- legacy::PassManager PM;
- MCContext *Ctx;
- if (TM.addPassesToEmitMC(PM, Ctx, ObjStream))
- llvm_unreachable("Target does not support MC emission.");
- PM.run(M);
- }
-
- auto ObjBuffer =
- llvm::make_unique<SmallVectorMemoryBuffer>(std::move(ObjBufferSV));
- auto Obj =
- object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
-
- if (Obj) {
- notifyObjectCompiled(M, *ObjBuffer);
- return std::move(ObjBuffer);
- }
-
- // TODO: Actually report errors helpfully.
- consumeError(Obj.takeError());
- return nullptr;
- }
+ CompileResult operator()(Module &M);
private:
-
- CompileResult tryToLoadFromObjectCache(const Module &M) {
- if (!ObjCache)
- return CompileResult();
-
- return ObjCache->getObject(&M);
- }
-
- void notifyObjectCompiled(const Module &M, const MemoryBuffer &ObjBuffer) {
- if (ObjCache)
- ObjCache->notifyObjectCompiled(&M, ObjBuffer.getMemBufferRef());
- }
+ CompileResult tryToLoadFromObjectCache(const Module &M);
+ void notifyObjectCompiled(const Module &M, const MemoryBuffer &ObjBuffer);
TargetMachine &TM;
ObjectCache *ObjCache = nullptr;
@@ -107,16 +59,11 @@
class ConcurrentIRCompiler {
public:
ConcurrentIRCompiler(JITTargetMachineBuilder JTMB,
- ObjectCache *ObjCache = nullptr)
- : JTMB(std::move(JTMB)), ObjCache(ObjCache) {}
+ ObjectCache *ObjCache = nullptr);
void setObjectCache(ObjectCache *ObjCache) { this->ObjCache = ObjCache; }
- std::unique_ptr<MemoryBuffer> operator()(Module &M) {
- auto TM = cantFail(JTMB.createTargetMachine());
- SimpleCompiler C(*TM, ObjCache);
- return C(M);
- }
+ std::unique_ptr<MemoryBuffer> operator()(Module &M);
private:
JITTargetMachineBuilder JTMB;
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Core.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Core.h
index 299247a..016fd82 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Core.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Core.h
@@ -33,6 +33,7 @@
class MaterializationUnit;
class MaterializationResponsibility;
class JITDylib;
+enum class SymbolState : uint8_t;
/// VModuleKey provides a unique identifier (allocated and managed by
/// ExecutionSessions) for a module added to the JIT.
@@ -56,6 +57,18 @@
/// A list of (JITDylib*, bool) pairs.
using JITDylibSearchList = std::vector<std::pair<JITDylib *, bool>>;
+struct SymbolAliasMapEntry {
+ SymbolAliasMapEntry() = default;
+ SymbolAliasMapEntry(SymbolStringPtr Aliasee, JITSymbolFlags AliasFlags)
+ : Aliasee(std::move(Aliasee)), AliasFlags(AliasFlags) {}
+
+ SymbolStringPtr Aliasee;
+ JITSymbolFlags AliasFlags;
+};
+
+/// A map of Symbols to (Symbol, Flags) pairs.
+using SymbolAliasMap = DenseMap<SymbolStringPtr, SymbolAliasMapEntry>;
+
/// Render a SymbolStringPtr.
raw_ostream &operator<<(raw_ostream &OS, const SymbolStringPtr &Sym);
@@ -87,12 +100,15 @@
/// Render a JITDylibSearchList.
raw_ostream &operator<<(raw_ostream &OS, const JITDylibSearchList &JDs);
+/// Render a SymbolAliasMap.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolAliasMap &Aliases);
+
+/// Render a SymbolState.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolState &S);
+
/// Callback to notify client that symbols have been resolved.
using SymbolsResolvedCallback = std::function<void(Expected<SymbolMap>)>;
-/// Callback to notify client that symbols are ready for execution.
-using SymbolsReadyCallback = std::function<void(Error)>;
-
/// Callback to register the dependencies for a given query.
using RegisterDependenciesFunction =
std::function<void(const SymbolDependenceMap &)>;
@@ -174,7 +190,7 @@
/// Note: The returned flags may have transient flags (Lazy, Materializing)
/// set. These should be stripped with JITSymbolFlags::stripTransientFlags
/// before using.
- const SymbolFlagsMap &getSymbols() { return SymbolFlags; }
+ const SymbolFlagsMap &getSymbols() const { return SymbolFlags; }
/// Returns the names of any symbols covered by this
/// MaterializationResponsibility object that have queries pending. This
@@ -188,12 +204,12 @@
/// symbols must be ones covered by this MaterializationResponsibility
/// instance. Individual calls to this method may resolve a subset of the
/// symbols, but all symbols must have been resolved prior to calling emit.
- void resolve(const SymbolMap &Symbols);
+ void notifyResolved(const SymbolMap &Symbols);
/// Notifies the target JITDylib (and any pending queries on that JITDylib)
/// that all symbols covered by this MaterializationResponsibility instance
/// have been emitted.
- void emit();
+ void notifyEmitted();
/// Adds new symbols to the JITDylib and this responsibility instance.
/// JITDylib entries start out in the materializing state.
@@ -333,18 +349,6 @@
std::move(Symbols), std::move(K));
}
-struct SymbolAliasMapEntry {
- SymbolAliasMapEntry() = default;
- SymbolAliasMapEntry(SymbolStringPtr Aliasee, JITSymbolFlags AliasFlags)
- : Aliasee(std::move(Aliasee)), AliasFlags(AliasFlags) {}
-
- SymbolStringPtr Aliasee;
- JITSymbolFlags AliasFlags;
-};
-
-/// A map of Symbols to (Symbol, Flags) pairs.
-using SymbolAliasMap = DenseMap<SymbolStringPtr, SymbolAliasMapEntry>;
-
/// A materialization unit for symbol aliases. Allows existing symbols to be
/// aliased with alternate flags.
class ReExportsMaterializationUnit : public MaterializationUnit {
@@ -418,7 +422,7 @@
ReexportsGenerator(JITDylib &SourceJD, bool MatchNonExported = false,
SymbolPredicate Allow = SymbolPredicate());
- SymbolNameSet operator()(JITDylib &JD, const SymbolNameSet &Names);
+ Expected<SymbolNameSet> operator()(JITDylib &JD, const SymbolNameSet &Names);
private:
JITDylib &SourceJD;
@@ -426,6 +430,15 @@
SymbolPredicate Allow;
};
+/// Represents the state that a symbol has reached during materialization.
+enum class SymbolState : uint8_t {
+ Invalid, /// No symbol should be in this state.
+ NeverSearched, /// Added to the symbol table, never queried.
+ Materializing, /// Queried, materialization begun.
+ Resolved, /// Assigned address, still materializing.
+ Ready = 0x3f /// Ready and safe for clients to access.
+};
+
/// A symbol query that returns results via a callback when results are
/// ready.
///
@@ -436,38 +449,30 @@
friend class JITSymbolResolverAdapter;
public:
-
- /// Create a query for the given symbols, notify-resolved and
- /// notify-ready callbacks.
+ /// Create a query for the given symbols. The NotifyComplete
+ /// callback will be called once all queried symbols reach the given
+ /// minimum state.
AsynchronousSymbolQuery(const SymbolNameSet &Symbols,
- SymbolsResolvedCallback NotifySymbolsResolved,
- SymbolsReadyCallback NotifySymbolsReady);
+ SymbolState RequiredState,
+ SymbolsResolvedCallback NotifyComplete);
- /// Set the resolved symbol information for the given symbol name.
- void resolve(const SymbolStringPtr &Name, JITEvaluatedSymbol Sym);
+ /// Notify the query that a requested symbol has reached the required state.
+ void notifySymbolMetRequiredState(const SymbolStringPtr &Name,
+ JITEvaluatedSymbol Sym);
/// Returns true if all symbols covered by this query have been
/// resolved.
- bool isFullyResolved() const { return NotYetResolvedCount == 0; }
+ bool isComplete() const { return OutstandingSymbolsCount == 0; }
- /// Call the NotifySymbolsResolved callback.
+ /// Call the NotifyComplete callback.
///
- /// This should only be called if all symbols covered by the query have been
- /// resolved.
- void handleFullyResolved();
-
- /// Notify the query that a requested symbol is ready for execution.
- void notifySymbolReady();
-
- /// Returns true if all symbols covered by this query are ready.
- bool isFullyReady() const { return NotYetReadyCount == 0; }
-
- /// Calls the NotifySymbolsReady callback.
- ///
- /// This should only be called if all symbols covered by this query are ready.
- void handleFullyReady();
+ /// This should only be called if all symbols covered by the query have
+ /// reached the specified state.
+ void handleComplete();
private:
+ SymbolState getRequiredState() { return RequiredState; }
+
void addQueryDependence(JITDylib &JD, SymbolStringPtr Name);
void removeQueryDependence(JITDylib &JD, const SymbolStringPtr &Name);
@@ -478,12 +483,11 @@
void detach();
- SymbolsResolvedCallback NotifySymbolsResolved;
- SymbolsReadyCallback NotifySymbolsReady;
+ SymbolsResolvedCallback NotifyComplete;
SymbolDependenceMap QueryRegistrations;
SymbolMap ResolvedSymbols;
- size_t NotYetResolvedCount;
- size_t NotYetReadyCount;
+ size_t OutstandingSymbolsCount;
+ SymbolState RequiredState;
};
/// A symbol table that supports asynchoronous symbol queries.
@@ -497,7 +501,7 @@
friend class ExecutionSession;
friend class MaterializationResponsibility;
public:
- using GeneratorFunction = std::function<SymbolNameSet(
+ using GeneratorFunction = std::function<Expected<SymbolNameSet>(
JITDylib &Parent, const SymbolNameSet &Names)>;
using AsynchronousSymbolQuerySet =
@@ -595,7 +599,7 @@
/// 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);
+ Expected<SymbolFlagsMap> lookupFlags(const SymbolNameSet &Names);
/// Dump current JITDylib state to OS.
void dump(raw_ostream &OS);
@@ -608,8 +612,8 @@
/// and the query will not be applied. The Query is not failed and can be
/// re-used in a subsequent lookup once the symbols have been added, or
/// manually failed.
- SymbolNameSet legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
- SymbolNameSet Names);
+ Expected<SymbolNameSet>
+ legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q, SymbolNameSet Names);
private:
using AsynchronousSymbolQueryList =
@@ -626,40 +630,92 @@
DenseMap<SymbolStringPtr, std::shared_ptr<UnmaterializedInfo>>;
struct MaterializingInfo {
- AsynchronousSymbolQueryList PendingQueries;
SymbolDependenceMap Dependants;
SymbolDependenceMap UnemittedDependencies;
bool IsEmitted = false;
+
+ void addQuery(std::shared_ptr<AsynchronousSymbolQuery> Q);
+ void removeQuery(const AsynchronousSymbolQuery &Q);
+ AsynchronousSymbolQueryList takeQueriesMeeting(SymbolState RequiredState);
+ AsynchronousSymbolQueryList takeAllQueries();
+ bool hasQueriesPending() const { return !PendingQueries.empty(); }
+ const AsynchronousSymbolQueryList &pendingQueries() const {
+ return PendingQueries;
+ }
+
+ private:
+ AsynchronousSymbolQueryList PendingQueries;
};
using MaterializingInfosMap = DenseMap<SymbolStringPtr, MaterializingInfo>;
- using LookupImplActionFlags = enum {
- None = 0,
- NotifyFullyResolved = 1 << 0U,
- NotifyFullyReady = 1 << 1U,
- LLVM_MARK_AS_BITMASK_ENUM(NotifyFullyReady)
+ class SymbolTableEntry {
+ public:
+ SymbolTableEntry() = default;
+ SymbolTableEntry(JITSymbolFlags Flags)
+ : Flags(Flags), State(static_cast<uint8_t>(SymbolState::NeverSearched)),
+ MaterializerAttached(false), PendingRemoval(false) {}
+
+ JITTargetAddress getAddress() const { return Addr; }
+ JITSymbolFlags getFlags() const { return Flags; }
+ SymbolState getState() const { return static_cast<SymbolState>(State); }
+
+ bool isInMaterializationPhase() const {
+ return getState() == SymbolState::Materializing ||
+ getState() == SymbolState::Resolved;
+ }
+
+ bool hasMaterializerAttached() const { return MaterializerAttached; }
+ bool isPendingRemoval() const { return PendingRemoval; }
+
+ void setAddress(JITTargetAddress Addr) { this->Addr = Addr; }
+ void setFlags(JITSymbolFlags Flags) { this->Flags = Flags; }
+ void setState(SymbolState State) {
+ assert(static_cast<uint8_t>(State) < (1 << 6) &&
+ "State does not fit in bitfield");
+ this->State = static_cast<uint8_t>(State);
+ }
+
+ void setMaterializerAttached(bool MaterializerAttached) {
+ this->MaterializerAttached = MaterializerAttached;
+ }
+
+ void setPendingRemoval(bool PendingRemoval) {
+ this->PendingRemoval = PendingRemoval;
+ }
+
+ JITEvaluatedSymbol getSymbol() const {
+ return JITEvaluatedSymbol(Addr, Flags);
+ }
+
+ private:
+ JITTargetAddress Addr = 0;
+ JITSymbolFlags Flags;
+ uint8_t State : 6;
+ uint8_t MaterializerAttached : 1;
+ uint8_t PendingRemoval : 1;
};
+ using SymbolTable = DenseMap<SymbolStringPtr, SymbolTableEntry>;
+
JITDylib(ExecutionSession &ES, std::string Name);
Error defineImpl(MaterializationUnit &MU);
- SymbolNameSet lookupFlagsImpl(SymbolFlagsMap &Flags,
- const SymbolNameSet &Names);
+ Expected<SymbolNameSet> lookupFlagsImpl(SymbolFlagsMap &Flags,
+ const SymbolNameSet &Names);
- void lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q,
- SymbolNameSet &Unresolved, bool MatchNonExported,
- MaterializationUnitList &MUs);
+ Error lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q,
+ SymbolNameSet &Unresolved, bool MatchNonExported,
+ MaterializationUnitList &MUs);
void lodgeQueryImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
SymbolNameSet &Unresolved, bool MatchNonExported,
MaterializationUnitList &MUs);
- LookupImplActionFlags
- lookupImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
- std::vector<std::unique_ptr<MaterializationUnit>> &MUs,
- SymbolNameSet &Unresolved);
+ bool lookupImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
+ std::vector<std::unique_ptr<MaterializationUnit>> &MUs,
+ SymbolNameSet &Unresolved);
void detachQueryHelper(AsynchronousSymbolQuery &Q,
const SymbolNameSet &QuerySymbols);
@@ -685,7 +741,7 @@
ExecutionSession &ES;
std::string JITDylibName;
- SymbolMap Symbols;
+ SymbolTable Symbols;
UnmaterializedInfosMap UnmaterializedInfos;
MaterializingInfosMap MaterializingInfos;
GeneratorFunction DefGenerator;
@@ -726,7 +782,15 @@
/// the ExecutionSession.
JITDylib &getMainJITDylib();
+ /// Return a pointer to the "name" JITDylib.
+ /// Ownership of JITDylib remains within Execution Session
+ JITDylib *getJITDylibByName(StringRef Name);
+
/// Add a new JITDylib to this ExecutionSession.
+ ///
+ /// The JITDylib Name is required to be unique. Clients should verify that
+ /// names are not being re-used (e.g. by calling getJITDylibByName) if names
+ /// are based on user input.
JITDylib &createJITDylib(std::string Name,
bool AddToMainDylibSearchOrder = true);
@@ -768,7 +832,7 @@
/// Do not use -- this will be removed soon.
Expected<SymbolMap>
legacyLookup(LegacyAsyncLookupFunction AsyncLookup, SymbolNameSet Names,
- bool WaiUntilReady,
+ SymbolState RequiredState,
RegisterDependenciesFunction RegisterDependencies);
/// Search the given JITDylib list for the given symbols.
@@ -778,11 +842,8 @@
/// (hidden visibility) symbols in that dylib (true means match against
/// non-exported symbols, false means do not match).
///
- /// The OnResolve callback will be called once all requested symbols are
- /// resolved, or if an error occurs prior to resolution.
- ///
- /// The OnReady callback will be called once all requested symbols are ready,
- /// or if an error occurs after resolution but before all symbols are ready.
+ /// The NotifyComplete callback will be called once all requested symbols
+ /// reach the required state.
///
/// If all symbols are found, the RegisterDependencies function will be called
/// while the session lock is held. This gives clients a chance to register
@@ -794,7 +855,7 @@
/// client to get an address to call) then the value NoDependenciesToRegister
/// can be used.
void lookup(const JITDylibSearchList &SearchOrder, SymbolNameSet Symbols,
- SymbolsResolvedCallback OnResolve, SymbolsReadyCallback OnReady,
+ SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete,
RegisterDependenciesFunction RegisterDependencies);
/// Blocking version of lookup above. Returns the resolved symbol map.
@@ -806,9 +867,9 @@
/// error will be reported via reportErrors.
Expected<SymbolMap> lookup(const JITDylibSearchList &SearchOrder,
const SymbolNameSet &Symbols,
+ SymbolState RequiredState = SymbolState::Ready,
RegisterDependenciesFunction RegisterDependencies =
- NoDependenciesToRegister,
- bool WaitUntilReady = true);
+ NoDependenciesToRegister);
/// Convenience version of blocking lookup.
/// Searches each of the JITDylibs in the search order in turn for the given
@@ -831,10 +892,11 @@
/// Materialize the given unit.
void dispatchMaterialization(JITDylib &JD,
std::unique_ptr<MaterializationUnit> MU) {
- LLVM_DEBUG(runSessionLocked([&]() {
- dbgs() << "Compiling, for " << JD.getName() << ", " << *MU
- << "\n";
- }););
+ LLVM_DEBUG({
+ runSessionLocked([&]() {
+ dbgs() << "Dispatching " << *MU << " for " << JD.getName() << "\n";
+ });
+ });
DispatchMaterialization(JD, std::move(MU));
}
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
index 40dd415..ae3ab8c 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
@@ -217,28 +217,29 @@
/// Create a DynamicLibrarySearchGenerator that searches for symbols in the
/// given sys::DynamicLibrary.
+ ///
/// If the Allow predicate is given then only symbols matching the predicate
- /// will be searched for in the DynamicLibrary. If the predicate is not given
- /// then all symbols will be searched for.
- DynamicLibrarySearchGenerator(sys::DynamicLibrary Dylib, const DataLayout &DL,
+ /// will be searched for. If the predicate is not given then all symbols will
+ /// be searched for.
+ DynamicLibrarySearchGenerator(sys::DynamicLibrary Dylib, char GlobalPrefix,
SymbolPredicate Allow = SymbolPredicate());
/// Permanently loads the library at the given path and, on success, returns
/// a DynamicLibrarySearchGenerator that will search it for symbol definitions
/// in the library. On failure returns the reason the library failed to load.
static Expected<DynamicLibrarySearchGenerator>
- Load(const char *FileName, const DataLayout &DL,
+ Load(const char *FileName, char GlobalPrefix,
SymbolPredicate Allow = SymbolPredicate());
/// Creates a DynamicLibrarySearchGenerator that searches for symbols in
/// the current process.
static Expected<DynamicLibrarySearchGenerator>
- GetForCurrentProcess(const DataLayout &DL,
+ GetForCurrentProcess(char GlobalPrefix,
SymbolPredicate Allow = SymbolPredicate()) {
- return Load(nullptr, DL, std::move(Allow));
+ return Load(nullptr, GlobalPrefix, std::move(Allow));
}
- SymbolNameSet operator()(JITDylib &JD, const SymbolNameSet &Names);
+ Expected<SymbolNameSet> operator()(JITDylib &JD, const SymbolNameSet &Names);
private:
sys::DynamicLibrary Dylib;
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
index 2ea9ac1..a7ed537 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
@@ -146,13 +146,13 @@
std::error_code EC;
auto TrampolineBlock =
sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(
- sys::Process::getPageSize(), nullptr,
+ sys::Process::getPageSizeEstimate(), nullptr,
sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC));
if (EC)
return errorCodeToError(EC);
unsigned NumTrampolines =
- (sys::Process::getPageSize() - ORCABI::PointerSize) /
+ (sys::Process::getPageSizeEstimate() - ORCABI::PointerSize) /
ORCABI::TrampolineSize;
uint8_t *TrampolineMem = static_cast<uint8_t *>(TrampolineBlock.base());
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LLJIT.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LLJIT.h
index b0ef20d..b54c7d8 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LLJIT.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LLJIT.h
@@ -20,35 +20,49 @@
#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
-#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
#include "llvm/Support/ThreadPool.h"
namespace llvm {
namespace orc {
+class LLJITBuilderState;
+class LLLazyJITBuilderState;
+
/// A pre-fabricated ORC JIT stack that can serve as an alternative to MCJIT.
+///
+/// Create instances using LLJITBuilder.
class LLJIT {
+ template <typename, typename, typename> friend class LLJITBuilderSetters;
+
public:
+ static Expected<std::unique_ptr<LLJIT>> Create(LLJITBuilderState &S);
/// Destruct this instance. If a multi-threaded instance, waits for all
/// compile threads to complete.
~LLJIT();
- /// Create an LLJIT instance.
- /// If NumCompileThreads is not equal to zero, creates a multi-threaded
- /// LLJIT with the given number of compile threads.
- static Expected<std::unique_ptr<LLJIT>>
- Create(JITTargetMachineBuilder JTMB, DataLayout DL,
- unsigned NumCompileThreads = 0);
-
/// Returns the ExecutionSession for this instance.
ExecutionSession &getExecutionSession() { return *ES; }
+ /// Returns a reference to the DataLayout for this instance.
+ const DataLayout &getDataLayout() const { return DL; }
+
/// Returns a reference to the JITDylib representing the JIT'd main program.
JITDylib &getMainJITDylib() { return Main; }
+ /// Returns the JITDylib with the given name, or nullptr if no JITDylib with
+ /// that name exists.
+ JITDylib *getJITDylibByName(StringRef Name) {
+ return ES->getJITDylibByName(Name);
+ }
+
/// Create a new JITDylib with the given name and return a reference to it.
+ ///
+ /// JITDylib names must be unique. If the given name is derived from user
+ /// input or elsewhere in the environment then the client should check
+ /// (e.g. by calling getJITDylibByName) that the given name is not already in
+ /// use.
JITDylib &createJITDylib(std::string Name) {
return ES->createJITDylib(std::move(Name));
}
@@ -56,8 +70,6 @@
/// Convenience method for defining an absolute symbol.
Error defineAbsolute(StringRef Name, JITEvaluatedSymbol Address);
- /// Convenience method for defining an
-
/// Adds an IR module to the given JITDylib.
Error addIRModule(JITDylib &JD, ThreadSafeModule TSM);
@@ -103,17 +115,14 @@
Error runDestructors() { return DtorRunner.run(); }
/// Returns a reference to the ObjLinkingLayer
- RTDyldObjectLinkingLayer &getObjLinkingLayer() { return ObjLinkingLayer; }
+ ObjectLayer &getObjLinkingLayer() { return *ObjLinkingLayer; }
protected:
+ static std::unique_ptr<ObjectLayer>
+ createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES);
/// Create an LLJIT instance with a single compile thread.
- LLJIT(std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM,
- DataLayout DL);
-
- /// Create an LLJIT instance with multiple compile threads.
- LLJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
- DataLayout DL, unsigned NumCompileThreads);
+ LLJIT(LLJITBuilderState &S, Error &Err);
std::string mangle(StringRef UnmangledName);
@@ -127,8 +136,8 @@
DataLayout DL;
std::unique_ptr<ThreadPool> CompileThreads;
- RTDyldObjectLinkingLayer ObjLinkingLayer;
- IRCompileLayer CompileLayer;
+ std::unique_ptr<ObjectLayer> ObjLinkingLayer;
+ std::unique_ptr<IRCompileLayer> CompileLayer;
CtorDtorRunner CtorRunner, DtorRunner;
};
@@ -136,25 +145,20 @@
/// An extended version of LLJIT that supports lazy function-at-a-time
/// compilation of LLVM IR.
class LLLazyJIT : public LLJIT {
-public:
+ template <typename, typename, typename> friend class LLJITBuilderSetters;
- /// Create an LLLazyJIT instance.
- /// If NumCompileThreads is not equal to zero, creates a multi-threaded
- /// LLLazyJIT with the given number of compile threads.
- static Expected<std::unique_ptr<LLLazyJIT>>
- Create(JITTargetMachineBuilder JTMB, DataLayout DL,
- JITTargetAddress ErrorAddr, unsigned NumCompileThreads = 0);
+public:
/// Set an IR transform (e.g. pass manager pipeline) to run on each function
/// when it is compiled.
void setLazyCompileTransform(IRTransformLayer::TransformFunction Transform) {
- TransformLayer.setTransform(std::move(Transform));
+ TransformLayer->setTransform(std::move(Transform));
}
/// Sets the partition function.
void
setPartitionFunction(CompileOnDemandLayer::PartitionFunction Partition) {
- CODLayer.setPartitionFunction(std::move(Partition));
+ CODLayer->setPartitionFunction(std::move(Partition));
}
/// Add a module to be lazily compiled to JITDylib JD.
@@ -168,24 +172,144 @@
private:
// Create a single-threaded LLLazyJIT instance.
- LLLazyJIT(std::unique_ptr<ExecutionSession> ES,
- std::unique_ptr<TargetMachine> TM, DataLayout DL,
- std::unique_ptr<LazyCallThroughManager> LCTMgr,
- std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder);
-
- // Create a multi-threaded LLLazyJIT instance.
- LLLazyJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
- DataLayout DL, unsigned NumCompileThreads,
- std::unique_ptr<LazyCallThroughManager> LCTMgr,
- std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder);
+ LLLazyJIT(LLLazyJITBuilderState &S, Error &Err);
std::unique_ptr<LazyCallThroughManager> LCTMgr;
- std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder;
-
- IRTransformLayer TransformLayer;
- CompileOnDemandLayer CODLayer;
+ std::unique_ptr<IRTransformLayer> TransformLayer;
+ std::unique_ptr<CompileOnDemandLayer> CODLayer;
};
+class LLJITBuilderState {
+public:
+ using CreateObjectLinkingLayerFunction =
+ std::function<std::unique_ptr<ObjectLayer>(ExecutionSession &)>;
+
+ std::unique_ptr<ExecutionSession> ES;
+ Optional<JITTargetMachineBuilder> JTMB;
+ CreateObjectLinkingLayerFunction CreateObjectLinkingLayer;
+ unsigned NumCompileThreads = 0;
+
+ /// Called prior to JIT class construcion to fix up defaults.
+ Error prepareForConstruction();
+};
+
+template <typename JITType, typename SetterImpl, typename State>
+class LLJITBuilderSetters {
+public:
+ /// Set the JITTargetMachineBuilder for this instance.
+ ///
+ /// If this method is not called, JITTargetMachineBuilder::detectHost will be
+ /// used to construct a default target machine builder for the host platform.
+ SetterImpl &setJITTargetMachineBuilder(JITTargetMachineBuilder JTMB) {
+ impl().JTMB = std::move(JTMB);
+ return impl();
+ }
+
+ /// Return a reference to the JITTargetMachineBuilder.
+ ///
+ Optional<JITTargetMachineBuilder> &getJITTargetMachineBuilder() {
+ return impl().JTMB;
+ }
+
+ /// Set an ObjectLinkingLayer creation function.
+ ///
+ /// If this method is not called, a default creation function will be used
+ /// that will construct an RTDyldObjectLinkingLayer.
+ SetterImpl &setCreateObjectLinkingLayer(
+ LLJITBuilderState::CreateObjectLinkingLayerFunction
+ CreateObjectLinkingLayer) {
+ impl().CreateObjectLinkingLayer = std::move(CreateObjectLinkingLayer);
+ return impl();
+ }
+
+ /// Set the number of compile threads to use.
+ ///
+ /// If set to zero, compilation will be performed on the execution thread when
+ /// JITing in-process. If set to any other number N, a thread pool of N
+ /// threads will be created for compilation.
+ ///
+ /// If this method is not called, behavior will be as if it were called with
+ /// a zero argument.
+ SetterImpl &setNumCompileThreads(unsigned NumCompileThreads) {
+ impl().NumCompileThreads = NumCompileThreads;
+ return impl();
+ }
+
+ /// Create an instance of the JIT.
+ Expected<std::unique_ptr<JITType>> create() {
+ if (auto Err = impl().prepareForConstruction())
+ return std::move(Err);
+
+ Error Err = Error::success();
+ std::unique_ptr<JITType> J(new JITType(impl(), Err));
+ if (Err)
+ return std::move(Err);
+ return std::move(J);
+ }
+
+protected:
+ SetterImpl &impl() { return static_cast<SetterImpl &>(*this); }
+};
+
+/// Constructs LLJIT instances.
+class LLJITBuilder
+ : public LLJITBuilderState,
+ public LLJITBuilderSetters<LLJIT, LLJITBuilder, LLJITBuilderState> {};
+
+class LLLazyJITBuilderState : public LLJITBuilderState {
+ friend class LLLazyJIT;
+
+public:
+ using IndirectStubsManagerBuilderFunction =
+ std::function<std::unique_ptr<IndirectStubsManager>()>;
+
+ Triple TT;
+ JITTargetAddress LazyCompileFailureAddr = 0;
+ std::unique_ptr<LazyCallThroughManager> LCTMgr;
+ IndirectStubsManagerBuilderFunction ISMBuilder;
+
+ Error prepareForConstruction();
+};
+
+template <typename JITType, typename SetterImpl, typename State>
+class LLLazyJITBuilderSetters
+ : public LLJITBuilderSetters<JITType, SetterImpl, State> {
+public:
+ /// Set the address in the target address to call if a lazy compile fails.
+ ///
+ /// If this method is not called then the value will default to 0.
+ SetterImpl &setLazyCompileFailureAddr(JITTargetAddress Addr) {
+ this->impl().LazyCompileFailureAddr = Addr;
+ return this->impl();
+ }
+
+ /// Set the lazy-callthrough manager.
+ ///
+ /// If this method is not called then a default, in-process lazy callthrough
+ /// manager for the host platform will be used.
+ SetterImpl &
+ setLazyCallthroughManager(std::unique_ptr<LazyCallThroughManager> LCTMgr) {
+ this->impl().LCTMgr = std::move(LCTMgr);
+ return this->impl();
+ }
+
+ /// Set the IndirectStubsManager builder function.
+ ///
+ /// If this method is not called then a default, in-process
+ /// IndirectStubsManager builder for the host platform will be used.
+ SetterImpl &setIndirectStubsManagerBuilder(
+ LLLazyJITBuilderState::IndirectStubsManagerBuilderFunction ISMBuilder) {
+ this->impl().ISMBuilder = std::move(ISMBuilder);
+ return this->impl();
+ }
+};
+
+/// Constructs LLLazyJIT instances.
+class LLLazyJITBuilder
+ : public LLLazyJITBuilderState,
+ public LLLazyJITBuilderSetters<LLLazyJIT, LLLazyJITBuilder,
+ LLLazyJITBuilderState> {};
+
} // End namespace orc
} // End namespace llvm
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
index fdf64d0..e5c5feb 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
@@ -34,8 +34,8 @@
/// Lazy-emitting IR layer.
///
-/// This layer accepts LLVM IR Modules (via addModule), but does not
-/// immediately emit them the layer below. Instead, emissing to the base layer
+/// This layer accepts LLVM IR Modules (via addModule) but does not
+/// immediately emit them the layer below. Instead, emission to the base layer
/// is deferred until the first time the client requests the address (via
/// JITSymbol::getAddress) for a symbol contained in this layer.
template <typename BaseLayerT> class LazyEmittingLayer {
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Legacy.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Legacy.h
index e0e5526..f9cbbf6 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Legacy.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Legacy.h
@@ -148,8 +148,8 @@
for (auto &S : Symbols) {
if (JITSymbol Sym = FindSymbol(*S)) {
if (auto Addr = Sym.getAddress()) {
- Query.resolve(S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
- Query.notifySymbolReady();
+ Query.notifySymbolMetRequiredState(
+ S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
NewSymbolsResolved = true;
} else {
ES.legacyFailQuery(Query, Addr.takeError());
@@ -162,11 +162,8 @@
SymbolsNotFound.insert(S);
}
- if (NewSymbolsResolved && Query.isFullyResolved())
- Query.handleFullyResolved();
-
- if (NewSymbolsResolved && Query.isFullyReady())
- Query.handleFullyReady();
+ if (NewSymbolsResolved && Query.isComplete())
+ Query.handleComplete();
return SymbolsNotFound;
}
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
new file mode 100644
index 0000000..c1e7d27
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
@@ -0,0 +1,165 @@
+//===-- ObjectLinkingLayer.h - JITLink-based jit linking layer --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Contains the definition for an JITLink-based, in-process object linking
+// layer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
+#define LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ExecutionEngine/JITLink/JITLink.h"
+#include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/Layer.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <list>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+
+namespace jitlink {
+class EHFrameRegistrar;
+} // namespace jitlink
+
+namespace object {
+class ObjectFile;
+} // namespace object
+
+namespace orc {
+
+class ObjectLinkingLayerJITLinkContext;
+
+/// An ObjectLayer implementation built on JITLink.
+///
+/// Clients can use this class to add relocatable object files to an
+/// ExecutionSession, and it typically serves as the base layer (underneath
+/// a compiling layer like IRCompileLayer) for the rest of the JIT.
+class ObjectLinkingLayer : public ObjectLayer {
+ friend class ObjectLinkingLayerJITLinkContext;
+
+public:
+ /// Plugin instances can be added to the ObjectLinkingLayer to receive
+ /// callbacks when code is loaded or emitted, and when JITLink is being
+ /// configured.
+ class Plugin {
+ public:
+ virtual ~Plugin();
+ virtual void modifyPassConfig(MaterializationResponsibility &MR,
+ const Triple &TT,
+ jitlink::PassConfiguration &Config) {}
+ virtual void notifyLoaded(MaterializationResponsibility &MR) {}
+ virtual Error notifyEmitted(MaterializationResponsibility &MR) {
+ return Error::success();
+ }
+ virtual Error notifyRemovingModule(VModuleKey K) {
+ return Error::success();
+ }
+ virtual Error notifyRemovingAllModules() { return Error::success(); }
+ };
+
+ /// Construct an ObjectLinkingLayer with the given NotifyLoaded,
+ /// and NotifyEmitted functors.
+ ObjectLinkingLayer(ExecutionSession &ES,
+ jitlink::JITLinkMemoryManager &MemMgr);
+
+ /// Destruct an ObjectLinkingLayer.
+ ~ObjectLinkingLayer();
+
+ /// Add a pass-config modifier.
+ ObjectLinkingLayer &addPlugin(std::unique_ptr<Plugin> P) {
+ std::lock_guard<std::mutex> Lock(LayerMutex);
+ Plugins.push_back(std::move(P));
+ return *this;
+ }
+
+ /// Emit the object.
+ void emit(MaterializationResponsibility R,
+ std::unique_ptr<MemoryBuffer> O) override;
+
+ /// Instructs this ObjectLinkingLayer instance to override the symbol flags
+ /// found in the AtomGraph with the flags supplied by the
+ /// MaterializationResponsibility instance. This is a workaround to support
+ /// symbol visibility in COFF, which does not use the libObject's
+ /// SF_Exported flag. Use only when generating / adding COFF object files.
+ ///
+ /// FIXME: We should be able to remove this if/when COFF properly tracks
+ /// exported symbols.
+ ObjectLinkingLayer &
+ setOverrideObjectFlagsWithResponsibilityFlags(bool OverrideObjectFlags) {
+ this->OverrideObjectFlags = OverrideObjectFlags;
+ return *this;
+ }
+
+ /// If set, this ObjectLinkingLayer instance will claim responsibility
+ /// for any symbols provided by a given object file that were not already in
+ /// the MaterializationResponsibility instance. Setting this flag allows
+ /// higher-level program representations (e.g. LLVM IR) to be added based on
+ /// only a subset of the symbols they provide, without having to write
+ /// intervening layers to scan and add the additional symbols. This trades
+ /// diagnostic quality for convenience however: If all symbols are enumerated
+ /// up-front then clashes can be detected and reported early (and usually
+ /// deterministically). If this option is set, clashes for the additional
+ /// symbols may not be detected until late, and detection may depend on
+ /// the flow of control through JIT'd code. Use with care.
+ ObjectLinkingLayer &
+ setAutoClaimResponsibilityForObjectSymbols(bool AutoClaimObjectSymbols) {
+ this->AutoClaimObjectSymbols = AutoClaimObjectSymbols;
+ return *this;
+ }
+
+private:
+ using AllocPtr = std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation>;
+
+ void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
+ jitlink::PassConfiguration &PassConfig);
+ void notifyLoaded(MaterializationResponsibility &MR);
+ Error notifyEmitted(MaterializationResponsibility &MR, AllocPtr Alloc);
+
+ Error removeModule(VModuleKey K);
+ Error removeAllModules();
+
+ mutable std::mutex LayerMutex;
+ jitlink::JITLinkMemoryManager &MemMgr;
+ bool OverrideObjectFlags = false;
+ bool AutoClaimObjectSymbols = false;
+ DenseMap<VModuleKey, AllocPtr> TrackedAllocs;
+ std::vector<AllocPtr> UntrackedAllocs;
+ std::vector<std::unique_ptr<Plugin>> Plugins;
+};
+
+class EHFrameRegistrationPlugin : public ObjectLinkingLayer::Plugin {
+public:
+ EHFrameRegistrationPlugin(jitlink::EHFrameRegistrar &Registrar);
+ Error notifyEmitted(MaterializationResponsibility &MR) override;
+ void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
+ jitlink::PassConfiguration &PassConfig) override;
+ Error notifyRemovingModule(VModuleKey K) override;
+ Error notifyRemovingAllModules() override;
+
+private:
+ jitlink::EHFrameRegistrar &Registrar;
+ DenseMap<MaterializationResponsibility *, JITTargetAddress> InProcessLinks;
+ DenseMap<VModuleKey, JITTargetAddress> TrackedEHFrameAddrs;
+ std::vector<JITTargetAddress> UntrackedEHFrameAddrs;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
index 9684481..4c8e2ea 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
@@ -299,13 +299,13 @@
std::error_code EC;
auto TrampolineBlock =
sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(
- sys::Process::getPageSize(), nullptr,
+ sys::Process::getPageSizeEstimate(), nullptr,
sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC));
if (EC)
return errorCodeToError(EC);
uint32_t NumTrampolines =
- (sys::Process::getPageSize() - TargetT::PointerSize) /
+ (sys::Process::getPageSizeEstimate() - TargetT::PointerSize) /
TargetT::TrampolineSize;
uint8_t *TrampolineMem = static_cast<uint8_t *>(TrampolineBlock.base());
@@ -335,7 +335,7 @@
handleGetRemoteInfo() {
std::string ProcessTriple = sys::getProcessTriple();
uint32_t PointerSize = TargetT::PointerSize;
- uint32_t PageSize = sys::Process::getPageSize();
+ uint32_t PageSize = sys::Process::getPageSizeEstimate();
uint32_t TrampolineSize = TargetT::TrampolineSize;
uint32_t IndirectStubSize = TargetT::IndirectStubsInfo::StubSize;
LLVM_DEBUG(dbgs() << " Remote info:\n"
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
index cd9ec36..479658b 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
@@ -43,22 +43,34 @@
const RuntimeDyld::LoadedObjectInfo &)>;
/// Functor for receiving finalization notifications.
- using NotifyEmittedFunction = std::function<void(VModuleKey)>;
+ using NotifyEmittedFunction =
+ std::function<void(VModuleKey, std::unique_ptr<MemoryBuffer>)>;
using GetMemoryManagerFunction =
std::function<std::unique_ptr<RuntimeDyld::MemoryManager>()>;
/// Construct an ObjectLinkingLayer with the given NotifyLoaded,
/// and NotifyEmitted functors.
- RTDyldObjectLinkingLayer(
- ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager,
- NotifyLoadedFunction NotifyLoaded = NotifyLoadedFunction(),
- NotifyEmittedFunction NotifyEmitted = NotifyEmittedFunction());
+ RTDyldObjectLinkingLayer(ExecutionSession &ES,
+ GetMemoryManagerFunction GetMemoryManager);
/// Emit the object.
void emit(MaterializationResponsibility R,
std::unique_ptr<MemoryBuffer> O) override;
+ /// Set the NotifyLoaded callback.
+ RTDyldObjectLinkingLayer &setNotifyLoaded(NotifyLoadedFunction NotifyLoaded) {
+ this->NotifyLoaded = std::move(NotifyLoaded);
+ return *this;
+ }
+
+ /// Set the NotifyEmitted callback.
+ RTDyldObjectLinkingLayer &
+ setNotifyEmitted(NotifyEmittedFunction NotifyEmitted) {
+ this->NotifyEmitted = std::move(NotifyEmitted);
+ return *this;
+ }
+
/// Set the 'ProcessAllSections' flag.
///
/// If set to true, all sections in each object file will be allocated using
@@ -108,7 +120,8 @@
std::map<StringRef, JITEvaluatedSymbol> Resolved,
std::set<StringRef> &InternalSymbols);
- void onObjEmit(VModuleKey K, MaterializationResponsibility &R, Error Err);
+ void onObjEmit(VModuleKey K, std::unique_ptr<MemoryBuffer> ObjBuffer,
+ MaterializationResponsibility &R, Error Err);
mutable std::mutex RTDyldLayerMutex;
GetMemoryManagerFunction GetMemoryManager;
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h
index 39fa74b..c354f6c 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h
@@ -50,25 +50,20 @@
class SymbolStringPtr {
friend class SymbolStringPool;
friend struct DenseMapInfo<SymbolStringPtr>;
- friend bool operator==(const SymbolStringPtr &LHS,
- const SymbolStringPtr &RHS);
- friend bool operator<(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS);
-
- static SymbolStringPool::PoolMapEntry Tombstone;
public:
SymbolStringPtr() = default;
SymbolStringPtr(const SymbolStringPtr &Other)
: S(Other.S) {
- if (S)
+ if (isRealPoolEntry(S))
++S->getValue();
}
SymbolStringPtr& operator=(const SymbolStringPtr &Other) {
- if (S)
+ if (isRealPoolEntry(S))
--S->getValue();
S = Other.S;
- if (S)
+ if (isRealPoolEntry(S))
++S->getValue();
return *this;
}
@@ -78,7 +73,7 @@
}
SymbolStringPtr& operator=(SymbolStringPtr &&Other) {
- if (S)
+ if (isRealPoolEntry(S))
--S->getValue();
S = nullptr;
std::swap(S, Other.S);
@@ -86,35 +81,65 @@
}
~SymbolStringPtr() {
- if (S)
+ if (isRealPoolEntry(S))
--S->getValue();
}
StringRef operator*() const { return S->first(); }
+ friend bool operator==(const SymbolStringPtr &LHS,
+ const SymbolStringPtr &RHS) {
+ return LHS.S == RHS.S;
+ }
+
+ friend bool operator!=(const SymbolStringPtr &LHS,
+ const SymbolStringPtr &RHS) {
+ return !(LHS == RHS);
+ }
+
+ friend bool operator<(const SymbolStringPtr &LHS,
+ const SymbolStringPtr &RHS) {
+ return LHS.S < RHS.S;
+ }
+
private:
+ using PoolEntryPtr = SymbolStringPool::PoolMapEntry *;
SymbolStringPtr(SymbolStringPool::PoolMapEntry *S)
: S(S) {
- if (S)
+ if (isRealPoolEntry(S))
++S->getValue();
}
- SymbolStringPool::PoolMapEntry *S = nullptr;
+ // Returns false for null, empty, and tombstone values, true otherwise.
+ bool isRealPoolEntry(PoolEntryPtr P) {
+ return ((reinterpret_cast<uintptr_t>(P) - 1) & InvalidPtrMask) !=
+ InvalidPtrMask;
+ }
+
+ static SymbolStringPtr getEmptyVal() {
+ return SymbolStringPtr(reinterpret_cast<PoolEntryPtr>(EmptyBitPattern));
+ }
+
+ static SymbolStringPtr getTombstoneVal() {
+ return SymbolStringPtr(reinterpret_cast<PoolEntryPtr>(TombstoneBitPattern));
+ }
+
+ constexpr static uintptr_t EmptyBitPattern =
+ std::numeric_limits<uintptr_t>::max()
+ << PointerLikeTypeTraits<PoolEntryPtr>::NumLowBitsAvailable;
+
+ constexpr static uintptr_t TombstoneBitPattern =
+ (std::numeric_limits<uintptr_t>::max() - 1)
+ << PointerLikeTypeTraits<PoolEntryPtr>::NumLowBitsAvailable;
+
+ constexpr static uintptr_t InvalidPtrMask =
+ (std::numeric_limits<uintptr_t>::max() - 3)
+ << PointerLikeTypeTraits<PoolEntryPtr>::NumLowBitsAvailable;
+
+ PoolEntryPtr S = nullptr;
};
-inline bool operator==(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) {
- return LHS.S == RHS.S;
-}
-
-inline bool operator!=(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) {
- return !(LHS == RHS);
-}
-
-inline bool operator<(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) {
- return LHS.S < RHS.S;
-}
-
inline SymbolStringPool::~SymbolStringPool() {
#ifndef NDEBUG
clearDeadEntries();
@@ -150,16 +175,15 @@
struct DenseMapInfo<orc::SymbolStringPtr> {
static orc::SymbolStringPtr getEmptyKey() {
- return orc::SymbolStringPtr();
+ return orc::SymbolStringPtr::getEmptyVal();
}
static orc::SymbolStringPtr getTombstoneKey() {
- return orc::SymbolStringPtr(&orc::SymbolStringPtr::Tombstone);
+ return orc::SymbolStringPtr::getTombstoneVal();
}
- static unsigned getHashValue(orc::SymbolStringPtr V) {
- uintptr_t IV = reinterpret_cast<uintptr_t>(V.S);
- return unsigned(IV) ^ unsigned(IV >> 9);
+ static unsigned getHashValue(const orc::SymbolStringPtr &V) {
+ return DenseMapInfo<orc::SymbolStringPtr::PoolEntryPtr>::getHashValue(V.S);
}
static bool isEqual(const orc::SymbolStringPtr &LHS,