LLVM  9.0.0svn
LazyReexports.h
Go to the documentation of this file.
1 //===------ LazyReexports.h -- Utilities for lazy reexports -----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Lazy re-exports are similar to normal re-exports, except that for callable
10 // symbols the definitions are replaced with trampolines that will look up and
11 // call through to the re-exported symbol at runtime. This can be used to
12 // enable lazy compilation.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef LLVM_EXECUTIONENGINE_ORC_LAZYREEXPORTS_H
17 #define LLVM_EXECUTIONENGINE_ORC_LAZYREEXPORTS_H
18 
21 
22 namespace llvm {
23 
24 class Triple;
25 
26 namespace orc {
27 
28 /// Manages a set of 'lazy call-through' trampolines. These are compiler
29 /// re-entry trampolines that are pre-bound to look up a given symbol in a given
30 /// JITDylib, then jump to that address. Since compilation of symbols is
31 /// triggered on first lookup, these call-through trampolines can be used to
32 /// implement lazy compilation.
33 ///
34 /// The easiest way to construct these call-throughs is using the lazyReexport
35 /// function.
37 public:
38  /// Clients will want to take some action on first resolution, e.g. updating
39  /// a stub pointer. Instances of this class can be used to implement this.
41  public:
43 
44  /// Called the first time a lazy call through is executed and the target
45  /// symbol resolved.
46  virtual Error operator()(JITDylib &SourceJD,
48  JITTargetAddress ResolvedAddr) = 0;
49 
50  private:
51  virtual void anchor();
52  };
53 
54  template <typename NotifyResolvedImpl>
56  public:
57  NotifyResolvedFunctionImpl(NotifyResolvedImpl NotifyResolved)
58  : NotifyResolved(std::move(NotifyResolved)) {}
60  JITTargetAddress ResolvedAddr) {
61  return NotifyResolved(SourceJD, SymbolName, ResolvedAddr);
62  }
63 
64  private:
65  NotifyResolvedImpl NotifyResolved;
66  };
67 
68  /// Create a shared NotifyResolvedFunction from a given type that is
69  /// callable with the correct signature.
70  template <typename NotifyResolvedImpl>
71  static std::unique_ptr<NotifyResolvedFunction>
72  createNotifyResolvedFunction(NotifyResolvedImpl NotifyResolved) {
73  return llvm::make_unique<NotifyResolvedFunctionImpl<NotifyResolvedImpl>>(
74  std::move(NotifyResolved));
75  }
76 
77  // Return a free call-through trampoline and bind it to look up and call
78  // through to the given symbol.
81  std::shared_ptr<NotifyResolvedFunction> NotifyResolved);
82 
83 protected:
85  JITTargetAddress ErrorHandlerAddr,
86  std::unique_ptr<TrampolinePool> TP);
87 
89 
90  void setTrampolinePool(std::unique_ptr<TrampolinePool> TP) {
91  this->TP = std::move(TP);
92  }
93 
94 private:
95  using ReexportsMap =
96  std::map<JITTargetAddress, std::pair<JITDylib *, SymbolStringPtr>>;
97 
98  using NotifiersMap =
99  std::map<JITTargetAddress, std::shared_ptr<NotifyResolvedFunction>>;
100 
101  std::mutex LCTMMutex;
102  ExecutionSession &ES;
103  JITTargetAddress ErrorHandlerAddr;
104  std::unique_ptr<TrampolinePool> TP;
105  ReexportsMap Reexports;
106  NotifiersMap Notifiers;
107 };
108 
109 /// A lazy call-through manager that builds trampolines in the current process.
111 private:
113  JITTargetAddress ErrorHandlerAddr)
114  : LazyCallThroughManager(ES, ErrorHandlerAddr, nullptr) {}
115 
116  template <typename ORCABI> Error init() {
118  [this](JITTargetAddress TrampolineAddr) {
119  return callThroughToSymbol(TrampolineAddr);
120  });
121 
122  if (!TP)
123  return TP.takeError();
124 
125  setTrampolinePool(std::move(*TP));
126  return Error::success();
127  }
128 
129 public:
130  /// Create a LocalLazyCallThroughManager using the given ABI. See
131  /// createLocalLazyCallThroughManager.
132  template <typename ORCABI>
134  Create(ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr) {
135  auto LLCTM = std::unique_ptr<LocalLazyCallThroughManager>(
136  new LocalLazyCallThroughManager(ES, ErrorHandlerAddr));
137 
138  if (auto Err = LLCTM->init<ORCABI>())
139  return std::move(Err);
140 
141  return std::move(LLCTM);
142  }
143 };
144 
145 /// Create a LocalLazyCallThroughManager from the given triple and execution
146 /// session.
149  JITTargetAddress ErrorHandlerAddr);
150 
151 /// A materialization unit that builds lazy re-exports. These are callable
152 /// entry points that call through to the given symbols.
153 /// Unlike a 'true' re-export, the address of the lazy re-export will not
154 /// match the address of the re-exported symbol, but calling it will behave
155 /// the same as calling the re-exported symbol.
157 public:
159  IndirectStubsManager &ISManager,
160  JITDylib &SourceJD,
161  SymbolAliasMap CallableAliases,
162  VModuleKey K);
163 
164  StringRef getName() const override;
165 
166 private:
167  void materialize(MaterializationResponsibility R) override;
168  void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
169  static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases);
170 
171  LazyCallThroughManager &LCTManager;
172  IndirectStubsManager &ISManager;
173  JITDylib &SourceJD;
174  SymbolAliasMap CallableAliases;
175  std::shared_ptr<LazyCallThroughManager::NotifyResolvedFunction>
176  NotifyResolved;
177 };
178 
179 /// Define lazy-reexports based on the given SymbolAliasMap. Each lazy re-export
180 /// is a callable symbol that will look up and dispatch to the given aliasee on
181 /// first call. All subsequent calls will go directly to the aliasee.
182 inline std::unique_ptr<LazyReexportsMaterializationUnit>
184  IndirectStubsManager &ISManager, JITDylib &SourceJD,
185  SymbolAliasMap CallableAliases, VModuleKey K = VModuleKey()) {
186  return llvm::make_unique<LazyReexportsMaterializationUnit>(
187  LCTManager, ISManager, SourceJD, std::move(CallableAliases),
188  std::move(K));
189 }
190 
191 } // End namespace orc
192 } // End namespace llvm
193 
194 #endif // LLVM_EXECUTIONENGINE_ORC_LAZYREEXPORTS_H
Base class for managing collections of named indirect stubs.
static Expected< std::unique_ptr< LocalLazyCallThroughManager > > Create(ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr)
Create a LocalLazyCallThroughManager using the given ABI.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
static std::unique_ptr< NotifyResolvedFunction > createNotifyResolvedFunction(NotifyResolvedImpl NotifyResolved)
Create a shared NotifyResolvedFunction from a given type that is callable with the correct signature...
Definition: LazyReexports.h:72
Clients will want to take some action on first resolution, e.g.
Definition: LazyReexports.h:40
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
uint64_t VModuleKey
VModuleKey provides a unique identifier (allocated and managed by ExecutionSessions) for a module add...
Definition: Core.h:39
static Expected< std::unique_ptr< LocalTrampolinePool > > Create(GetTrampolineLandingFunction GetTrampolineLanding)
Creates a LocalTrampolinePool with the given RunCallback function.
JITTargetAddress callThroughToSymbol(JITTargetAddress TrampolineAddr)
Definition: BitVector.h:937
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
static StringRef getName(Value *V)
Tagged union holding either a T or a Error.
Definition: CachePruning.h:22
A materialization unit that builds lazy re-exports.
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Definition: Core.h:154
uint64_t JITTargetAddress
Represents an address in the target process&#39;s address space.
Definition: JITSymbol.h:40
virtual Error operator()(JITDylib &SourceJD, const SymbolStringPtr &SymbolName, JITTargetAddress ResolvedAddr)=0
Called the first time a lazy call through is executed and the target symbol resolved.
Pointer to a pooled string representing a symbol name.
LazyCallThroughManager(ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr, std::unique_ptr< TrampolinePool > TP)
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:427
Error operator()(JITDylib &SourceJD, const SymbolStringPtr &SymbolName, JITTargetAddress ResolvedAddr)
Called the first time a lazy call through is executed and the target symbol resolved.
Definition: LazyReexports.h:59
void setTrampolinePool(std::unique_ptr< TrampolinePool > TP)
Definition: LazyReexports.h:90
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:43
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group...
Definition: Core.h:251
static ErrorSuccess success()
Create a success value.
Definition: Error.h:326
Expected< std::unique_ptr< LazyCallThroughManager > > createLocalLazyCallThroughManager(const Triple &T, ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr)
Create a LocalLazyCallThroughManager from the given triple and execution session. ...
std::unique_ptr< LazyReexportsMaterializationUnit > lazyReexports(LazyCallThroughManager &LCTManager, IndirectStubsManager &ISManager, JITDylib &SourceJD, SymbolAliasMap CallableAliases, VModuleKey K=VModuleKey())
Define lazy-reexports based on the given SymbolAliasMap.
NotifyResolvedFunctionImpl(NotifyResolvedImpl NotifyResolved)
Definition: LazyReexports.h:57
An ExecutionSession represents a running JIT program.
Definition: Core.h:696
Expected< JITTargetAddress > getCallThroughTrampoline(JITDylib &SourceJD, SymbolStringPtr SymbolName, std::shared_ptr< NotifyResolvedFunction > NotifyResolved)
A lazy call-through manager that builds trampolines in the current process.
Manages a set of &#39;lazy call-through&#39; trampolines.
Definition: LazyReexports.h:36
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
A symbol table that supports asynchoronous symbol queries.
Definition: Core.h:495