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