#ifndef LLVM_EXECUTIONENGINE_ORC_LAZYREEXPORTS_H
#define LLVM_EXECUTIONENGINE_ORC_LAZYREEXPORTS_H
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
#include "llvm/ExecutionEngine/Orc/Speculation.h"
/// function.
class LazyCallThroughManager {
public:
- /// Clients will want to take some action on first resolution, e.g. updating
- /// a stub pointer. Instances of this class can be used to implement this.
- class NotifyResolvedFunction {
- public:
- virtual ~NotifyResolvedFunction() {}
-
- /// Called the first time a lazy call through is executed and the target
- /// symbol resolved.
- virtual Error operator()(JITDylib &SourceJD,
- const SymbolStringPtr &SymbolName,
- JITTargetAddress ResolvedAddr) = 0;
-
- private:
- virtual void anchor();
- };
-
- template <typename NotifyResolvedImpl>
- class NotifyResolvedFunctionImpl : public NotifyResolvedFunction {
- public:
- NotifyResolvedFunctionImpl(NotifyResolvedImpl NotifyResolved)
- : NotifyResolved(std::move(NotifyResolved)) {}
- Error operator()(JITDylib &SourceJD, const SymbolStringPtr &SymbolName,
- JITTargetAddress ResolvedAddr) {
- return NotifyResolved(SourceJD, SymbolName, ResolvedAddr);
- }
-
- private:
- NotifyResolvedImpl NotifyResolved;
- };
-
- /// Create a shared NotifyResolvedFunction from a given type that is
- /// callable with the correct signature.
- template <typename NotifyResolvedImpl>
- static std::unique_ptr<NotifyResolvedFunction>
- createNotifyResolvedFunction(NotifyResolvedImpl NotifyResolved) {
- return std::make_unique<NotifyResolvedFunctionImpl<NotifyResolvedImpl>>(
- std::move(NotifyResolved));
- }
+ using NotifyResolvedFunction =
+ unique_function<Error(JITTargetAddress ResolvedAddr)>;
// Return a free call-through trampoline and bind it to look up and call
// through to the given symbol.
- Expected<JITTargetAddress> getCallThroughTrampoline(
- JITDylib &SourceJD, SymbolStringPtr SymbolName,
- std::shared_ptr<NotifyResolvedFunction> NotifyResolved);
+ Expected<JITTargetAddress>
+ getCallThroughTrampoline(JITDylib &SourceJD, SymbolStringPtr SymbolName,
+ NotifyResolvedFunction NotifyResolved);
protected:
LazyCallThroughManager(ExecutionSession &ES,
using ReexportsMap =
std::map<JITTargetAddress, std::pair<JITDylib *, SymbolStringPtr>>;
- using NotifiersMap =
- std::map<JITTargetAddress, std::shared_ptr<NotifyResolvedFunction>>;
+ using NotifiersMap = std::map<JITTargetAddress, NotifyResolvedFunction>;
std::mutex LCTMMutex;
ExecutionSession &ES;
IndirectStubsManager &ISManager;
JITDylib &SourceJD;
SymbolAliasMap CallableAliases;
- std::shared_ptr<LazyCallThroughManager::NotifyResolvedFunction>
- NotifyResolved;
ImplSymbolMap *AliaseeTable;
};
namespace llvm {
namespace orc {
-void LazyCallThroughManager::NotifyResolvedFunction::anchor() {}
-
LazyCallThroughManager::LazyCallThroughManager(
ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr,
std::unique_ptr<TrampolinePool> TP)
Expected<JITTargetAddress> LazyCallThroughManager::getCallThroughTrampoline(
JITDylib &SourceJD, SymbolStringPtr SymbolName,
- std::shared_ptr<NotifyResolvedFunction> NotifyResolved) {
+ NotifyResolvedFunction NotifyResolved) {
std::lock_guard<std::mutex> Lock(LCTMMutex);
auto Trampoline = TP->getTrampoline();
auto ResolvedAddr = LookupResult->getAddress();
- std::shared_ptr<NotifyResolvedFunction> NotifyResolved = nullptr;
+ NotifyResolvedFunction NotifyResolved;
{
std::lock_guard<std::mutex> Lock(LCTMMutex);
auto I = Notifiers.find(TrampolineAddr);
if (I != Notifiers.end()) {
- NotifyResolved = I->second;
+ NotifyResolved = std::move(I->second);
Notifiers.erase(I);
}
}
if (NotifyResolved) {
- if (auto Err = (*NotifyResolved)(*SourceJD, SymbolName, ResolvedAddr)) {
+ if (auto Err = NotifyResolved(ResolvedAddr)) {
ES.reportError(std::move(Err));
return ErrorHandlerAddr;
}
: MaterializationUnit(extractFlags(CallableAliases), std::move(K)),
LCTManager(LCTManager), ISManager(ISManager), SourceJD(SourceJD),
CallableAliases(std::move(CallableAliases)),
- NotifyResolved(LazyCallThroughManager::createNotifyResolvedFunction(
- [&ISManager](JITDylib &JD, const SymbolStringPtr &SymbolName,
- JITTargetAddress ResolvedAddr) {
- return ISManager.updatePointer(*SymbolName, ResolvedAddr);
- })),
AliaseeTable(SrcJDLoc) {}
StringRef LazyReexportsMaterializationUnit::getName() const {
for (auto &Alias : RequestedAliases) {
auto CallThroughTrampoline = LCTManager.getCallThroughTrampoline(
- SourceJD, Alias.second.Aliasee, NotifyResolved);
+ SourceJD, Alias.second.Aliasee,
+ [&ISManager = this->ISManager,
+ StubSym = Alias.first](JITTargetAddress ResolvedAddr) -> Error {
+ return ISManager.updatePointer(*StubSym, ResolvedAddr);
+ });
if (!CallThroughTrampoline) {
SourceJD.getExecutionSession().reportError(
})));
unsigned NotifyResolvedCount = 0;
- auto NotifyResolved = LazyCallThroughManager::createNotifyResolvedFunction(
- [&](JITDylib &JD, const SymbolStringPtr &SymbolName,
- JITTargetAddress ResolvedAddr) {
- ++NotifyResolvedCount;
- return Error::success();
- });
+ auto NotifyResolved = [&](JITTargetAddress ResolvedAddr) {
+ ++NotifyResolvedCount;
+ return Error::success();
+ };
auto CallThroughTrampoline = cantFail((*LCTM)->getCallThroughTrampoline(
JD, DummyTarget, std::move(NotifyResolved)));