[Orc] Add a new JITSymbol constructor to build a symbol from an existing address.

This constructor is more efficient for symbols that have already been emitted,
since it avoids the construction/execution of a std::function.

Update the ObjectLinkingLayer to use this new constructor where possible.

llvm-svn: 229973
This commit is contained in:
Lang Hames 2015-02-20 06:48:29 +00:00
parent a46d5a7438
commit 02be3f36a3
2 changed files with 37 additions and 11 deletions

View File

@ -28,10 +28,25 @@ class JITSymbol {
public:
typedef std::function<TargetAddress()> GetAddressFtor;
/// @brief Create a 'null' symbol that represents failure to find a symbol
/// definition.
JITSymbol(std::nullptr_t) : CachedAddr(0) {}
/// @brief Create a symbol for a definition with a known address.
JITSymbol(TargetAddress Addr)
: CachedAddr(Addr) {}
/// @brief Create a symbol for a definition that doesn't have a known address
/// yet.
/// @param GetAddress A functor to materialize a definition (fixing the
/// address) on demand.
///
/// This constructor allows a JIT layer to provide a reference to a symbol
/// definition without actually materializing the definition up front. The
/// user can materialize the definition at any time by calling the getAddress
/// method.
JITSymbol(GetAddressFtor GetAddress)
: CachedAddr(0), GetAddress(std::move(GetAddress)) {}
: CachedAddr(0), GetAddress(std::move(GetAddress)) {}
/// @brief Returns true if the symbol exists, false otherwise.
explicit operator bool() const { return CachedAddr || GetAddress; }

View File

@ -213,16 +213,27 @@ public:
/// given object set.
JITSymbol findSymbolIn(ObjSetHandleT H, StringRef Name,
bool ExportedSymbolsOnly) {
if (auto Addr = H->getSymbolAddress(Name, ExportedSymbolsOnly))
return JITSymbol(
[this, Addr, H](){
if (H->NeedsFinalization()) {
H->Finalize();
if (NotifyFinalized)
NotifyFinalized(H);
}
return Addr;
});
if (auto Addr = H->getSymbolAddress(Name, ExportedSymbolsOnly)) {
if (!H->NeedsFinalization()) {
// If this instance has already been finalized then we can just return
// the address.
return JITSymbol(Addr);
} else {
// If this instance needs finalization return a functor that will do it.
// The functor still needs to double-check whether finalization is
// required, in case someone else finalizes this set before the functor
// is called.
return JITSymbol(
[this, Addr, H]() {
if (H->NeedsFinalization()) {
H->Finalize();
if (NotifyFinalized)
NotifyFinalized(H);
}
return Addr;
});
}
}
return nullptr;
}