File: | llvm/include/llvm/ADT/FunctionExtras.h |
Warning: | line 187, column 5 Undefined or garbage value returned to caller |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===--- Core.cpp - Core ORC APIs (MaterializationUnit, JITDylib, etc.) ---===// | |||
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 | #include "llvm/ExecutionEngine/Orc/Core.h" | |||
10 | ||||
11 | #include "llvm/ADT/STLExtras.h" | |||
12 | #include "llvm/Config/llvm-config.h" | |||
13 | #include "llvm/ExecutionEngine/Orc/DebugUtils.h" | |||
14 | #include "llvm/ExecutionEngine/Orc/Shared/OrcError.h" | |||
15 | #include "llvm/Support/FormatVariadic.h" | |||
16 | #include "llvm/Support/MSVCErrorWorkarounds.h" | |||
17 | ||||
18 | #include <condition_variable> | |||
19 | #include <future> | |||
20 | ||||
21 | #define DEBUG_TYPE"orc" "orc" | |||
22 | ||||
23 | namespace llvm { | |||
24 | namespace orc { | |||
25 | ||||
26 | char ResourceTrackerDefunct::ID = 0; | |||
27 | char FailedToMaterialize::ID = 0; | |||
28 | char SymbolsNotFound::ID = 0; | |||
29 | char SymbolsCouldNotBeRemoved::ID = 0; | |||
30 | char MissingSymbolDefinitions::ID = 0; | |||
31 | char UnexpectedSymbolDefinitions::ID = 0; | |||
32 | ||||
33 | RegisterDependenciesFunction NoDependenciesToRegister = | |||
34 | RegisterDependenciesFunction(); | |||
35 | ||||
36 | void MaterializationUnit::anchor() {} | |||
37 | ||||
38 | ResourceTracker::ResourceTracker(JITDylibSP JD) { | |||
39 | assert((reinterpret_cast<uintptr_t>(JD.get()) & 0x1) == 0 &&(static_cast <bool> ((reinterpret_cast<uintptr_t> (JD.get()) & 0x1) == 0 && "JITDylib must be two byte aligned" ) ? void (0) : __assert_fail ("(reinterpret_cast<uintptr_t>(JD.get()) & 0x1) == 0 && \"JITDylib must be two byte aligned\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 40, __extension__ __PRETTY_FUNCTION__)) | |||
40 | "JITDylib must be two byte aligned")(static_cast <bool> ((reinterpret_cast<uintptr_t> (JD.get()) & 0x1) == 0 && "JITDylib must be two byte aligned" ) ? void (0) : __assert_fail ("(reinterpret_cast<uintptr_t>(JD.get()) & 0x1) == 0 && \"JITDylib must be two byte aligned\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 40, __extension__ __PRETTY_FUNCTION__)); | |||
41 | JD->Retain(); | |||
42 | JDAndFlag.store(reinterpret_cast<uintptr_t>(JD.get())); | |||
43 | } | |||
44 | ||||
45 | ResourceTracker::~ResourceTracker() { | |||
46 | getJITDylib().getExecutionSession().destroyResourceTracker(*this); | |||
47 | getJITDylib().Release(); | |||
48 | } | |||
49 | ||||
50 | Error ResourceTracker::remove() { | |||
51 | return getJITDylib().getExecutionSession().removeResourceTracker(*this); | |||
52 | } | |||
53 | ||||
54 | void ResourceTracker::transferTo(ResourceTracker &DstRT) { | |||
55 | getJITDylib().getExecutionSession().transferResourceTracker(DstRT, *this); | |||
56 | } | |||
57 | ||||
58 | void ResourceTracker::makeDefunct() { | |||
59 | uintptr_t Val = JDAndFlag.load(); | |||
60 | Val |= 0x1U; | |||
61 | JDAndFlag.store(Val); | |||
62 | } | |||
63 | ||||
64 | ResourceManager::~ResourceManager() {} | |||
65 | ||||
66 | ResourceTrackerDefunct::ResourceTrackerDefunct(ResourceTrackerSP RT) | |||
67 | : RT(std::move(RT)) {} | |||
68 | ||||
69 | std::error_code ResourceTrackerDefunct::convertToErrorCode() const { | |||
70 | return orcError(OrcErrorCode::UnknownORCError); | |||
71 | } | |||
72 | ||||
73 | void ResourceTrackerDefunct::log(raw_ostream &OS) const { | |||
74 | OS << "Resource tracker " << (void *)RT.get() << " became defunct"; | |||
75 | } | |||
76 | ||||
77 | FailedToMaterialize::FailedToMaterialize( | |||
78 | std::shared_ptr<SymbolDependenceMap> Symbols) | |||
79 | : Symbols(std::move(Symbols)) { | |||
80 | assert(!this->Symbols->empty() && "Can not fail to resolve an empty set")(static_cast <bool> (!this->Symbols->empty() && "Can not fail to resolve an empty set") ? void (0) : __assert_fail ("!this->Symbols->empty() && \"Can not fail to resolve an empty set\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 80, __extension__ __PRETTY_FUNCTION__)); | |||
81 | } | |||
82 | ||||
83 | std::error_code FailedToMaterialize::convertToErrorCode() const { | |||
84 | return orcError(OrcErrorCode::UnknownORCError); | |||
85 | } | |||
86 | ||||
87 | void FailedToMaterialize::log(raw_ostream &OS) const { | |||
88 | OS << "Failed to materialize symbols: " << *Symbols; | |||
89 | } | |||
90 | ||||
91 | SymbolsNotFound::SymbolsNotFound(SymbolNameSet Symbols) { | |||
92 | for (auto &Sym : Symbols) | |||
93 | this->Symbols.push_back(Sym); | |||
94 | assert(!this->Symbols.empty() && "Can not fail to resolve an empty set")(static_cast <bool> (!this->Symbols.empty() && "Can not fail to resolve an empty set") ? void (0) : __assert_fail ("!this->Symbols.empty() && \"Can not fail to resolve an empty set\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 94, __extension__ __PRETTY_FUNCTION__)); | |||
95 | } | |||
96 | ||||
97 | SymbolsNotFound::SymbolsNotFound(SymbolNameVector Symbols) | |||
98 | : Symbols(std::move(Symbols)) { | |||
99 | assert(!this->Symbols.empty() && "Can not fail to resolve an empty set")(static_cast <bool> (!this->Symbols.empty() && "Can not fail to resolve an empty set") ? void (0) : __assert_fail ("!this->Symbols.empty() && \"Can not fail to resolve an empty set\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 99, __extension__ __PRETTY_FUNCTION__)); | |||
100 | } | |||
101 | ||||
102 | std::error_code SymbolsNotFound::convertToErrorCode() const { | |||
103 | return orcError(OrcErrorCode::UnknownORCError); | |||
104 | } | |||
105 | ||||
106 | void SymbolsNotFound::log(raw_ostream &OS) const { | |||
107 | OS << "Symbols not found: " << Symbols; | |||
108 | } | |||
109 | ||||
110 | SymbolsCouldNotBeRemoved::SymbolsCouldNotBeRemoved(SymbolNameSet Symbols) | |||
111 | : Symbols(std::move(Symbols)) { | |||
112 | assert(!this->Symbols.empty() && "Can not fail to resolve an empty set")(static_cast <bool> (!this->Symbols.empty() && "Can not fail to resolve an empty set") ? void (0) : __assert_fail ("!this->Symbols.empty() && \"Can not fail to resolve an empty set\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 112, __extension__ __PRETTY_FUNCTION__)); | |||
113 | } | |||
114 | ||||
115 | std::error_code SymbolsCouldNotBeRemoved::convertToErrorCode() const { | |||
116 | return orcError(OrcErrorCode::UnknownORCError); | |||
117 | } | |||
118 | ||||
119 | void SymbolsCouldNotBeRemoved::log(raw_ostream &OS) const { | |||
120 | OS << "Symbols could not be removed: " << Symbols; | |||
121 | } | |||
122 | ||||
123 | std::error_code MissingSymbolDefinitions::convertToErrorCode() const { | |||
124 | return orcError(OrcErrorCode::MissingSymbolDefinitions); | |||
125 | } | |||
126 | ||||
127 | void MissingSymbolDefinitions::log(raw_ostream &OS) const { | |||
128 | OS << "Missing definitions in module " << ModuleName | |||
129 | << ": " << Symbols; | |||
130 | } | |||
131 | ||||
132 | std::error_code UnexpectedSymbolDefinitions::convertToErrorCode() const { | |||
133 | return orcError(OrcErrorCode::UnexpectedSymbolDefinitions); | |||
134 | } | |||
135 | ||||
136 | void UnexpectedSymbolDefinitions::log(raw_ostream &OS) const { | |||
137 | OS << "Unexpected definitions in module " << ModuleName | |||
138 | << ": " << Symbols; | |||
139 | } | |||
140 | ||||
141 | AsynchronousSymbolQuery::AsynchronousSymbolQuery( | |||
142 | const SymbolLookupSet &Symbols, SymbolState RequiredState, | |||
143 | SymbolsResolvedCallback NotifyComplete) | |||
144 | : NotifyComplete(std::move(NotifyComplete)), RequiredState(RequiredState) { | |||
145 | assert(RequiredState >= SymbolState::Resolved &&(static_cast <bool> (RequiredState >= SymbolState::Resolved && "Cannot query for a symbols that have not reached the resolve state " "yet") ? void (0) : __assert_fail ("RequiredState >= SymbolState::Resolved && \"Cannot query for a symbols that have not reached the resolve state \" \"yet\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 147, __extension__ __PRETTY_FUNCTION__)) | |||
146 | "Cannot query for a symbols that have not reached the resolve state "(static_cast <bool> (RequiredState >= SymbolState::Resolved && "Cannot query for a symbols that have not reached the resolve state " "yet") ? void (0) : __assert_fail ("RequiredState >= SymbolState::Resolved && \"Cannot query for a symbols that have not reached the resolve state \" \"yet\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 147, __extension__ __PRETTY_FUNCTION__)) | |||
147 | "yet")(static_cast <bool> (RequiredState >= SymbolState::Resolved && "Cannot query for a symbols that have not reached the resolve state " "yet") ? void (0) : __assert_fail ("RequiredState >= SymbolState::Resolved && \"Cannot query for a symbols that have not reached the resolve state \" \"yet\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 147, __extension__ __PRETTY_FUNCTION__)); | |||
148 | ||||
149 | OutstandingSymbolsCount = Symbols.size(); | |||
150 | ||||
151 | for (auto &KV : Symbols) | |||
152 | ResolvedSymbols[KV.first] = nullptr; | |||
153 | } | |||
154 | ||||
155 | void AsynchronousSymbolQuery::notifySymbolMetRequiredState( | |||
156 | const SymbolStringPtr &Name, JITEvaluatedSymbol Sym) { | |||
157 | auto I = ResolvedSymbols.find(Name); | |||
158 | assert(I != ResolvedSymbols.end() &&(static_cast <bool> (I != ResolvedSymbols.end() && "Resolving symbol outside the requested set") ? void (0) : __assert_fail ("I != ResolvedSymbols.end() && \"Resolving symbol outside the requested set\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 159, __extension__ __PRETTY_FUNCTION__)) | |||
159 | "Resolving symbol outside the requested set")(static_cast <bool> (I != ResolvedSymbols.end() && "Resolving symbol outside the requested set") ? void (0) : __assert_fail ("I != ResolvedSymbols.end() && \"Resolving symbol outside the requested set\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 159, __extension__ __PRETTY_FUNCTION__)); | |||
160 | assert(I->second.getAddress() == 0 && "Redundantly resolving symbol Name")(static_cast <bool> (I->second.getAddress() == 0 && "Redundantly resolving symbol Name") ? void (0) : __assert_fail ("I->second.getAddress() == 0 && \"Redundantly resolving symbol Name\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 160, __extension__ __PRETTY_FUNCTION__)); | |||
161 | ||||
162 | // If this is a materialization-side-effects-only symbol then drop it, | |||
163 | // otherwise update its map entry with its resolved address. | |||
164 | if (Sym.getFlags().hasMaterializationSideEffectsOnly()) | |||
165 | ResolvedSymbols.erase(I); | |||
166 | else | |||
167 | I->second = std::move(Sym); | |||
168 | --OutstandingSymbolsCount; | |||
169 | } | |||
170 | ||||
171 | void AsynchronousSymbolQuery::handleComplete() { | |||
172 | assert(OutstandingSymbolsCount == 0 &&(static_cast <bool> (OutstandingSymbolsCount == 0 && "Symbols remain, handleComplete called prematurely") ? void ( 0) : __assert_fail ("OutstandingSymbolsCount == 0 && \"Symbols remain, handleComplete called prematurely\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 173, __extension__ __PRETTY_FUNCTION__)) | |||
173 | "Symbols remain, handleComplete called prematurely")(static_cast <bool> (OutstandingSymbolsCount == 0 && "Symbols remain, handleComplete called prematurely") ? void ( 0) : __assert_fail ("OutstandingSymbolsCount == 0 && \"Symbols remain, handleComplete called prematurely\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 173, __extension__ __PRETTY_FUNCTION__)); | |||
174 | ||||
175 | auto TmpNotifyComplete = std::move(NotifyComplete); | |||
176 | NotifyComplete = SymbolsResolvedCallback(); | |||
177 | TmpNotifyComplete(std::move(ResolvedSymbols)); | |||
178 | } | |||
179 | ||||
180 | void AsynchronousSymbolQuery::handleFailed(Error Err) { | |||
181 | assert(QueryRegistrations.empty() && ResolvedSymbols.empty() &&(static_cast <bool> (QueryRegistrations.empty() && ResolvedSymbols.empty() && OutstandingSymbolsCount == 0 && "Query should already have been abandoned") ? void (0) : __assert_fail ("QueryRegistrations.empty() && ResolvedSymbols.empty() && OutstandingSymbolsCount == 0 && \"Query should already have been abandoned\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 183, __extension__ __PRETTY_FUNCTION__)) | |||
182 | OutstandingSymbolsCount == 0 &&(static_cast <bool> (QueryRegistrations.empty() && ResolvedSymbols.empty() && OutstandingSymbolsCount == 0 && "Query should already have been abandoned") ? void (0) : __assert_fail ("QueryRegistrations.empty() && ResolvedSymbols.empty() && OutstandingSymbolsCount == 0 && \"Query should already have been abandoned\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 183, __extension__ __PRETTY_FUNCTION__)) | |||
183 | "Query should already have been abandoned")(static_cast <bool> (QueryRegistrations.empty() && ResolvedSymbols.empty() && OutstandingSymbolsCount == 0 && "Query should already have been abandoned") ? void (0) : __assert_fail ("QueryRegistrations.empty() && ResolvedSymbols.empty() && OutstandingSymbolsCount == 0 && \"Query should already have been abandoned\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 183, __extension__ __PRETTY_FUNCTION__)); | |||
184 | NotifyComplete(std::move(Err)); | |||
185 | NotifyComplete = SymbolsResolvedCallback(); | |||
186 | } | |||
187 | ||||
188 | void AsynchronousSymbolQuery::addQueryDependence(JITDylib &JD, | |||
189 | SymbolStringPtr Name) { | |||
190 | bool Added = QueryRegistrations[&JD].insert(std::move(Name)).second; | |||
191 | (void)Added; | |||
192 | assert(Added && "Duplicate dependence notification?")(static_cast <bool> (Added && "Duplicate dependence notification?" ) ? void (0) : __assert_fail ("Added && \"Duplicate dependence notification?\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 192, __extension__ __PRETTY_FUNCTION__)); | |||
193 | } | |||
194 | ||||
195 | void AsynchronousSymbolQuery::removeQueryDependence( | |||
196 | JITDylib &JD, const SymbolStringPtr &Name) { | |||
197 | auto QRI = QueryRegistrations.find(&JD); | |||
198 | assert(QRI != QueryRegistrations.end() &&(static_cast <bool> (QRI != QueryRegistrations.end() && "No dependencies registered for JD") ? void (0) : __assert_fail ("QRI != QueryRegistrations.end() && \"No dependencies registered for JD\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 199, __extension__ __PRETTY_FUNCTION__)) | |||
199 | "No dependencies registered for JD")(static_cast <bool> (QRI != QueryRegistrations.end() && "No dependencies registered for JD") ? void (0) : __assert_fail ("QRI != QueryRegistrations.end() && \"No dependencies registered for JD\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 199, __extension__ __PRETTY_FUNCTION__)); | |||
200 | assert(QRI->second.count(Name) && "No dependency on Name in JD")(static_cast <bool> (QRI->second.count(Name) && "No dependency on Name in JD") ? void (0) : __assert_fail ("QRI->second.count(Name) && \"No dependency on Name in JD\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 200, __extension__ __PRETTY_FUNCTION__)); | |||
201 | QRI->second.erase(Name); | |||
202 | if (QRI->second.empty()) | |||
203 | QueryRegistrations.erase(QRI); | |||
204 | } | |||
205 | ||||
206 | void AsynchronousSymbolQuery::dropSymbol(const SymbolStringPtr &Name) { | |||
207 | auto I = ResolvedSymbols.find(Name); | |||
208 | assert(I != ResolvedSymbols.end() &&(static_cast <bool> (I != ResolvedSymbols.end() && "Redundant removal of weakly-referenced symbol") ? void (0) : __assert_fail ("I != ResolvedSymbols.end() && \"Redundant removal of weakly-referenced symbol\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 209, __extension__ __PRETTY_FUNCTION__)) | |||
209 | "Redundant removal of weakly-referenced symbol")(static_cast <bool> (I != ResolvedSymbols.end() && "Redundant removal of weakly-referenced symbol") ? void (0) : __assert_fail ("I != ResolvedSymbols.end() && \"Redundant removal of weakly-referenced symbol\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 209, __extension__ __PRETTY_FUNCTION__)); | |||
210 | ResolvedSymbols.erase(I); | |||
211 | --OutstandingSymbolsCount; | |||
212 | } | |||
213 | ||||
214 | void AsynchronousSymbolQuery::detach() { | |||
215 | ResolvedSymbols.clear(); | |||
216 | OutstandingSymbolsCount = 0; | |||
217 | for (auto &KV : QueryRegistrations) | |||
218 | KV.first->detachQueryHelper(*this, KV.second); | |||
219 | QueryRegistrations.clear(); | |||
220 | } | |||
221 | ||||
222 | AbsoluteSymbolsMaterializationUnit::AbsoluteSymbolsMaterializationUnit( | |||
223 | SymbolMap Symbols) | |||
224 | : MaterializationUnit(extractFlags(Symbols), nullptr), | |||
225 | Symbols(std::move(Symbols)) {} | |||
226 | ||||
227 | StringRef AbsoluteSymbolsMaterializationUnit::getName() const { | |||
228 | return "<Absolute Symbols>"; | |||
229 | } | |||
230 | ||||
231 | void AbsoluteSymbolsMaterializationUnit::materialize( | |||
232 | std::unique_ptr<MaterializationResponsibility> R) { | |||
233 | // No dependencies, so these calls can't fail. | |||
234 | cantFail(R->notifyResolved(Symbols)); | |||
| ||||
235 | cantFail(R->notifyEmitted()); | |||
236 | } | |||
237 | ||||
238 | void AbsoluteSymbolsMaterializationUnit::discard(const JITDylib &JD, | |||
239 | const SymbolStringPtr &Name) { | |||
240 | assert(Symbols.count(Name) && "Symbol is not part of this MU")(static_cast <bool> (Symbols.count(Name) && "Symbol is not part of this MU" ) ? void (0) : __assert_fail ("Symbols.count(Name) && \"Symbol is not part of this MU\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 240, __extension__ __PRETTY_FUNCTION__)); | |||
241 | Symbols.erase(Name); | |||
242 | } | |||
243 | ||||
244 | SymbolFlagsMap | |||
245 | AbsoluteSymbolsMaterializationUnit::extractFlags(const SymbolMap &Symbols) { | |||
246 | SymbolFlagsMap Flags; | |||
247 | for (const auto &KV : Symbols) | |||
248 | Flags[KV.first] = KV.second.getFlags(); | |||
249 | return Flags; | |||
250 | } | |||
251 | ||||
252 | ReExportsMaterializationUnit::ReExportsMaterializationUnit( | |||
253 | JITDylib *SourceJD, JITDylibLookupFlags SourceJDLookupFlags, | |||
254 | SymbolAliasMap Aliases) | |||
255 | : MaterializationUnit(extractFlags(Aliases), nullptr), SourceJD(SourceJD), | |||
256 | SourceJDLookupFlags(SourceJDLookupFlags), Aliases(std::move(Aliases)) {} | |||
257 | ||||
258 | StringRef ReExportsMaterializationUnit::getName() const { | |||
259 | return "<Reexports>"; | |||
260 | } | |||
261 | ||||
262 | void ReExportsMaterializationUnit::materialize( | |||
263 | std::unique_ptr<MaterializationResponsibility> R) { | |||
264 | ||||
265 | auto &ES = R->getTargetJITDylib().getExecutionSession(); | |||
266 | JITDylib &TgtJD = R->getTargetJITDylib(); | |||
267 | JITDylib &SrcJD = SourceJD ? *SourceJD : TgtJD; | |||
268 | ||||
269 | // Find the set of requested aliases and aliasees. Return any unrequested | |||
270 | // aliases back to the JITDylib so as to not prematurely materialize any | |||
271 | // aliasees. | |||
272 | auto RequestedSymbols = R->getRequestedSymbols(); | |||
273 | SymbolAliasMap RequestedAliases; | |||
274 | ||||
275 | for (auto &Name : RequestedSymbols) { | |||
276 | auto I = Aliases.find(Name); | |||
277 | assert(I != Aliases.end() && "Symbol not found in aliases map?")(static_cast <bool> (I != Aliases.end() && "Symbol not found in aliases map?" ) ? void (0) : __assert_fail ("I != Aliases.end() && \"Symbol not found in aliases map?\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 277, __extension__ __PRETTY_FUNCTION__)); | |||
278 | RequestedAliases[Name] = std::move(I->second); | |||
279 | Aliases.erase(I); | |||
280 | } | |||
281 | ||||
282 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { ES.runSessionLocked([&]() { dbgs() << "materializing reexports: target = " << TgtJD.getName() << ", source = " << SrcJD .getName() << " " << RequestedAliases << "\n" ; }); }; } } while (false) | |||
283 | ES.runSessionLocked([&]() {do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { ES.runSessionLocked([&]() { dbgs() << "materializing reexports: target = " << TgtJD.getName() << ", source = " << SrcJD .getName() << " " << RequestedAliases << "\n" ; }); }; } } while (false) | |||
284 | dbgs() << "materializing reexports: target = " << TgtJD.getName()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { ES.runSessionLocked([&]() { dbgs() << "materializing reexports: target = " << TgtJD.getName() << ", source = " << SrcJD .getName() << " " << RequestedAliases << "\n" ; }); }; } } while (false) | |||
285 | << ", source = " << SrcJD.getName() << " " << RequestedAliasesdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { ES.runSessionLocked([&]() { dbgs() << "materializing reexports: target = " << TgtJD.getName() << ", source = " << SrcJD .getName() << " " << RequestedAliases << "\n" ; }); }; } } while (false) | |||
286 | << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { ES.runSessionLocked([&]() { dbgs() << "materializing reexports: target = " << TgtJD.getName() << ", source = " << SrcJD .getName() << " " << RequestedAliases << "\n" ; }); }; } } while (false) | |||
287 | });do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { ES.runSessionLocked([&]() { dbgs() << "materializing reexports: target = " << TgtJD.getName() << ", source = " << SrcJD .getName() << " " << RequestedAliases << "\n" ; }); }; } } while (false) | |||
288 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { ES.runSessionLocked([&]() { dbgs() << "materializing reexports: target = " << TgtJD.getName() << ", source = " << SrcJD .getName() << " " << RequestedAliases << "\n" ; }); }; } } while (false); | |||
289 | ||||
290 | if (!Aliases.empty()) { | |||
291 | auto Err = SourceJD ? R->replace(reexports(*SourceJD, std::move(Aliases), | |||
292 | SourceJDLookupFlags)) | |||
293 | : R->replace(symbolAliases(std::move(Aliases))); | |||
294 | ||||
295 | if (Err) { | |||
296 | // FIXME: Should this be reported / treated as failure to materialize? | |||
297 | // Or should this be treated as a sanctioned bailing-out? | |||
298 | ES.reportError(std::move(Err)); | |||
299 | R->failMaterialization(); | |||
300 | return; | |||
301 | } | |||
302 | } | |||
303 | ||||
304 | // The OnResolveInfo struct will hold the aliases and responsibilty for each | |||
305 | // query in the list. | |||
306 | struct OnResolveInfo { | |||
307 | OnResolveInfo(std::unique_ptr<MaterializationResponsibility> R, | |||
308 | SymbolAliasMap Aliases) | |||
309 | : R(std::move(R)), Aliases(std::move(Aliases)) {} | |||
310 | ||||
311 | std::unique_ptr<MaterializationResponsibility> R; | |||
312 | SymbolAliasMap Aliases; | |||
313 | }; | |||
314 | ||||
315 | // Build a list of queries to issue. In each round we build a query for the | |||
316 | // largest set of aliases that we can resolve without encountering a chain of | |||
317 | // aliases (e.g. Foo -> Bar, Bar -> Baz). Such a chain would deadlock as the | |||
318 | // query would be waiting on a symbol that it itself had to resolve. Creating | |||
319 | // a new query for each link in such a chain eliminates the possibility of | |||
320 | // deadlock. In practice chains are likely to be rare, and this algorithm will | |||
321 | // usually result in a single query to issue. | |||
322 | ||||
323 | std::vector<std::pair<SymbolLookupSet, std::shared_ptr<OnResolveInfo>>> | |||
324 | QueryInfos; | |||
325 | while (!RequestedAliases.empty()) { | |||
326 | SymbolNameSet ResponsibilitySymbols; | |||
327 | SymbolLookupSet QuerySymbols; | |||
328 | SymbolAliasMap QueryAliases; | |||
329 | ||||
330 | // Collect as many aliases as we can without including a chain. | |||
331 | for (auto &KV : RequestedAliases) { | |||
332 | // Chain detected. Skip this symbol for this round. | |||
333 | if (&SrcJD == &TgtJD && (QueryAliases.count(KV.second.Aliasee) || | |||
334 | RequestedAliases.count(KV.second.Aliasee))) | |||
335 | continue; | |||
336 | ||||
337 | ResponsibilitySymbols.insert(KV.first); | |||
338 | QuerySymbols.add(KV.second.Aliasee, | |||
339 | KV.second.AliasFlags.hasMaterializationSideEffectsOnly() | |||
340 | ? SymbolLookupFlags::WeaklyReferencedSymbol | |||
341 | : SymbolLookupFlags::RequiredSymbol); | |||
342 | QueryAliases[KV.first] = std::move(KV.second); | |||
343 | } | |||
344 | ||||
345 | // Remove the aliases collected this round from the RequestedAliases map. | |||
346 | for (auto &KV : QueryAliases) | |||
347 | RequestedAliases.erase(KV.first); | |||
348 | ||||
349 | assert(!QuerySymbols.empty() && "Alias cycle detected!")(static_cast <bool> (!QuerySymbols.empty() && "Alias cycle detected!" ) ? void (0) : __assert_fail ("!QuerySymbols.empty() && \"Alias cycle detected!\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 349, __extension__ __PRETTY_FUNCTION__)); | |||
350 | ||||
351 | auto NewR = R->delegate(ResponsibilitySymbols); | |||
352 | if (!NewR) { | |||
353 | ES.reportError(NewR.takeError()); | |||
354 | R->failMaterialization(); | |||
355 | return; | |||
356 | } | |||
357 | ||||
358 | auto QueryInfo = std::make_shared<OnResolveInfo>(std::move(*NewR), | |||
359 | std::move(QueryAliases)); | |||
360 | QueryInfos.push_back( | |||
361 | make_pair(std::move(QuerySymbols), std::move(QueryInfo))); | |||
362 | } | |||
363 | ||||
364 | // Issue the queries. | |||
365 | while (!QueryInfos.empty()) { | |||
366 | auto QuerySymbols = std::move(QueryInfos.back().first); | |||
367 | auto QueryInfo = std::move(QueryInfos.back().second); | |||
368 | ||||
369 | QueryInfos.pop_back(); | |||
370 | ||||
371 | auto RegisterDependencies = [QueryInfo, | |||
372 | &SrcJD](const SymbolDependenceMap &Deps) { | |||
373 | // If there were no materializing symbols, just bail out. | |||
374 | if (Deps.empty()) | |||
375 | return; | |||
376 | ||||
377 | // Otherwise the only deps should be on SrcJD. | |||
378 | assert(Deps.size() == 1 && Deps.count(&SrcJD) &&(static_cast <bool> (Deps.size() == 1 && Deps.count (&SrcJD) && "Unexpected dependencies for reexports" ) ? void (0) : __assert_fail ("Deps.size() == 1 && Deps.count(&SrcJD) && \"Unexpected dependencies for reexports\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 379, __extension__ __PRETTY_FUNCTION__)) | |||
379 | "Unexpected dependencies for reexports")(static_cast <bool> (Deps.size() == 1 && Deps.count (&SrcJD) && "Unexpected dependencies for reexports" ) ? void (0) : __assert_fail ("Deps.size() == 1 && Deps.count(&SrcJD) && \"Unexpected dependencies for reexports\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 379, __extension__ __PRETTY_FUNCTION__)); | |||
380 | ||||
381 | auto &SrcJDDeps = Deps.find(&SrcJD)->second; | |||
382 | SymbolDependenceMap PerAliasDepsMap; | |||
383 | auto &PerAliasDeps = PerAliasDepsMap[&SrcJD]; | |||
384 | ||||
385 | for (auto &KV : QueryInfo->Aliases) | |||
386 | if (SrcJDDeps.count(KV.second.Aliasee)) { | |||
387 | PerAliasDeps = {KV.second.Aliasee}; | |||
388 | QueryInfo->R->addDependencies(KV.first, PerAliasDepsMap); | |||
389 | } | |||
390 | }; | |||
391 | ||||
392 | auto OnComplete = [QueryInfo](Expected<SymbolMap> Result) { | |||
393 | auto &ES = QueryInfo->R->getTargetJITDylib().getExecutionSession(); | |||
394 | if (Result) { | |||
395 | SymbolMap ResolutionMap; | |||
396 | for (auto &KV : QueryInfo->Aliases) { | |||
397 | assert((KV.second.AliasFlags.hasMaterializationSideEffectsOnly() ||(static_cast <bool> ((KV.second.AliasFlags.hasMaterializationSideEffectsOnly () || Result->count(KV.second.Aliasee)) && "Result map missing entry?" ) ? void (0) : __assert_fail ("(KV.second.AliasFlags.hasMaterializationSideEffectsOnly() || Result->count(KV.second.Aliasee)) && \"Result map missing entry?\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 399, __extension__ __PRETTY_FUNCTION__)) | |||
398 | Result->count(KV.second.Aliasee)) &&(static_cast <bool> ((KV.second.AliasFlags.hasMaterializationSideEffectsOnly () || Result->count(KV.second.Aliasee)) && "Result map missing entry?" ) ? void (0) : __assert_fail ("(KV.second.AliasFlags.hasMaterializationSideEffectsOnly() || Result->count(KV.second.Aliasee)) && \"Result map missing entry?\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 399, __extension__ __PRETTY_FUNCTION__)) | |||
399 | "Result map missing entry?")(static_cast <bool> ((KV.second.AliasFlags.hasMaterializationSideEffectsOnly () || Result->count(KV.second.Aliasee)) && "Result map missing entry?" ) ? void (0) : __assert_fail ("(KV.second.AliasFlags.hasMaterializationSideEffectsOnly() || Result->count(KV.second.Aliasee)) && \"Result map missing entry?\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 399, __extension__ __PRETTY_FUNCTION__)); | |||
400 | // Don't try to resolve materialization-side-effects-only symbols. | |||
401 | if (KV.second.AliasFlags.hasMaterializationSideEffectsOnly()) | |||
402 | continue; | |||
403 | ||||
404 | ResolutionMap[KV.first] = JITEvaluatedSymbol( | |||
405 | (*Result)[KV.second.Aliasee].getAddress(), KV.second.AliasFlags); | |||
406 | } | |||
407 | if (auto Err = QueryInfo->R->notifyResolved(ResolutionMap)) { | |||
408 | ES.reportError(std::move(Err)); | |||
409 | QueryInfo->R->failMaterialization(); | |||
410 | return; | |||
411 | } | |||
412 | if (auto Err = QueryInfo->R->notifyEmitted()) { | |||
413 | ES.reportError(std::move(Err)); | |||
414 | QueryInfo->R->failMaterialization(); | |||
415 | return; | |||
416 | } | |||
417 | } else { | |||
418 | ES.reportError(Result.takeError()); | |||
419 | QueryInfo->R->failMaterialization(); | |||
420 | } | |||
421 | }; | |||
422 | ||||
423 | ES.lookup(LookupKind::Static, | |||
424 | JITDylibSearchOrder({{&SrcJD, SourceJDLookupFlags}}), | |||
425 | QuerySymbols, SymbolState::Resolved, std::move(OnComplete), | |||
426 | std::move(RegisterDependencies)); | |||
427 | } | |||
428 | } | |||
429 | ||||
430 | void ReExportsMaterializationUnit::discard(const JITDylib &JD, | |||
431 | const SymbolStringPtr &Name) { | |||
432 | assert(Aliases.count(Name) &&(static_cast <bool> (Aliases.count(Name) && "Symbol not covered by this MaterializationUnit" ) ? void (0) : __assert_fail ("Aliases.count(Name) && \"Symbol not covered by this MaterializationUnit\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 433, __extension__ __PRETTY_FUNCTION__)) | |||
433 | "Symbol not covered by this MaterializationUnit")(static_cast <bool> (Aliases.count(Name) && "Symbol not covered by this MaterializationUnit" ) ? void (0) : __assert_fail ("Aliases.count(Name) && \"Symbol not covered by this MaterializationUnit\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 433, __extension__ __PRETTY_FUNCTION__)); | |||
434 | Aliases.erase(Name); | |||
435 | } | |||
436 | ||||
437 | SymbolFlagsMap | |||
438 | ReExportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) { | |||
439 | SymbolFlagsMap SymbolFlags; | |||
440 | for (auto &KV : Aliases) | |||
441 | SymbolFlags[KV.first] = KV.second.AliasFlags; | |||
442 | ||||
443 | return SymbolFlags; | |||
444 | } | |||
445 | ||||
446 | Expected<SymbolAliasMap> buildSimpleReexportsAliasMap(JITDylib &SourceJD, | |||
447 | SymbolNameSet Symbols) { | |||
448 | SymbolLookupSet LookupSet(Symbols); | |||
449 | auto Flags = SourceJD.getExecutionSession().lookupFlags( | |||
450 | LookupKind::Static, {{&SourceJD, JITDylibLookupFlags::MatchAllSymbols}}, | |||
451 | SymbolLookupSet(std::move(Symbols))); | |||
452 | ||||
453 | if (!Flags) | |||
454 | return Flags.takeError(); | |||
455 | ||||
456 | SymbolAliasMap Result; | |||
457 | for (auto &Name : Symbols) { | |||
458 | assert(Flags->count(Name) && "Missing entry in flags map")(static_cast <bool> (Flags->count(Name) && "Missing entry in flags map" ) ? void (0) : __assert_fail ("Flags->count(Name) && \"Missing entry in flags map\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 458, __extension__ __PRETTY_FUNCTION__)); | |||
459 | Result[Name] = SymbolAliasMapEntry(Name, (*Flags)[Name]); | |||
460 | } | |||
461 | ||||
462 | return Result; | |||
463 | } | |||
464 | ||||
465 | class InProgressLookupState { | |||
466 | public: | |||
467 | InProgressLookupState(LookupKind K, JITDylibSearchOrder SearchOrder, | |||
468 | SymbolLookupSet LookupSet, SymbolState RequiredState) | |||
469 | : K(K), SearchOrder(std::move(SearchOrder)), | |||
470 | LookupSet(std::move(LookupSet)), RequiredState(RequiredState) { | |||
471 | DefGeneratorCandidates = this->LookupSet; | |||
472 | } | |||
473 | virtual ~InProgressLookupState() {} | |||
474 | virtual void complete(std::unique_ptr<InProgressLookupState> IPLS) = 0; | |||
475 | virtual void fail(Error Err) = 0; | |||
476 | ||||
477 | LookupKind K; | |||
478 | JITDylibSearchOrder SearchOrder; | |||
479 | SymbolLookupSet LookupSet; | |||
480 | SymbolState RequiredState; | |||
481 | ||||
482 | std::unique_lock<std::mutex> GeneratorLock; | |||
483 | size_t CurSearchOrderIndex = 0; | |||
484 | bool NewJITDylib = true; | |||
485 | SymbolLookupSet DefGeneratorCandidates; | |||
486 | SymbolLookupSet DefGeneratorNonCandidates; | |||
487 | std::vector<std::weak_ptr<DefinitionGenerator>> CurDefGeneratorStack; | |||
488 | }; | |||
489 | ||||
490 | class InProgressLookupFlagsState : public InProgressLookupState { | |||
491 | public: | |||
492 | InProgressLookupFlagsState( | |||
493 | LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet LookupSet, | |||
494 | unique_function<void(Expected<SymbolFlagsMap>)> OnComplete) | |||
495 | : InProgressLookupState(K, std::move(SearchOrder), std::move(LookupSet), | |||
496 | SymbolState::NeverSearched), | |||
497 | OnComplete(std::move(OnComplete)) {} | |||
498 | ||||
499 | void complete(std::unique_ptr<InProgressLookupState> IPLS) override { | |||
500 | GeneratorLock = {}; // Unlock and release. | |||
501 | auto &ES = SearchOrder.front().first->getExecutionSession(); | |||
502 | ES.OL_completeLookupFlags(std::move(IPLS), std::move(OnComplete)); | |||
503 | } | |||
504 | ||||
505 | void fail(Error Err) override { | |||
506 | GeneratorLock = {}; // Unlock and release. | |||
507 | OnComplete(std::move(Err)); | |||
508 | } | |||
509 | ||||
510 | private: | |||
511 | unique_function<void(Expected<SymbolFlagsMap>)> OnComplete; | |||
512 | }; | |||
513 | ||||
514 | class InProgressFullLookupState : public InProgressLookupState { | |||
515 | public: | |||
516 | InProgressFullLookupState(LookupKind K, JITDylibSearchOrder SearchOrder, | |||
517 | SymbolLookupSet LookupSet, | |||
518 | SymbolState RequiredState, | |||
519 | std::shared_ptr<AsynchronousSymbolQuery> Q, | |||
520 | RegisterDependenciesFunction RegisterDependencies) | |||
521 | : InProgressLookupState(K, std::move(SearchOrder), std::move(LookupSet), | |||
522 | RequiredState), | |||
523 | Q(std::move(Q)), RegisterDependencies(std::move(RegisterDependencies)) { | |||
524 | } | |||
525 | ||||
526 | void complete(std::unique_ptr<InProgressLookupState> IPLS) override { | |||
527 | GeneratorLock = {}; // Unlock and release. | |||
528 | auto &ES = SearchOrder.front().first->getExecutionSession(); | |||
529 | ES.OL_completeLookup(std::move(IPLS), std::move(Q), | |||
530 | std::move(RegisterDependencies)); | |||
531 | } | |||
532 | ||||
533 | void fail(Error Err) override { | |||
534 | GeneratorLock = {}; | |||
535 | Q->detach(); | |||
536 | Q->handleFailed(std::move(Err)); | |||
537 | } | |||
538 | ||||
539 | private: | |||
540 | std::shared_ptr<AsynchronousSymbolQuery> Q; | |||
541 | RegisterDependenciesFunction RegisterDependencies; | |||
542 | }; | |||
543 | ||||
544 | ReexportsGenerator::ReexportsGenerator(JITDylib &SourceJD, | |||
545 | JITDylibLookupFlags SourceJDLookupFlags, | |||
546 | SymbolPredicate Allow) | |||
547 | : SourceJD(SourceJD), SourceJDLookupFlags(SourceJDLookupFlags), | |||
548 | Allow(std::move(Allow)) {} | |||
549 | ||||
550 | Error ReexportsGenerator::tryToGenerate(LookupState &LS, LookupKind K, | |||
551 | JITDylib &JD, | |||
552 | JITDylibLookupFlags JDLookupFlags, | |||
553 | const SymbolLookupSet &LookupSet) { | |||
554 | assert(&JD != &SourceJD && "Cannot re-export from the same dylib")(static_cast <bool> (&JD != &SourceJD && "Cannot re-export from the same dylib") ? void (0) : __assert_fail ("&JD != &SourceJD && \"Cannot re-export from the same dylib\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 554, __extension__ __PRETTY_FUNCTION__)); | |||
555 | ||||
556 | // Use lookupFlags to find the subset of symbols that match our lookup. | |||
557 | auto Flags = JD.getExecutionSession().lookupFlags( | |||
558 | K, {{&SourceJD, JDLookupFlags}}, LookupSet); | |||
559 | if (!Flags) | |||
560 | return Flags.takeError(); | |||
561 | ||||
562 | // Create an alias map. | |||
563 | orc::SymbolAliasMap AliasMap; | |||
564 | for (auto &KV : *Flags) | |||
565 | if (!Allow || Allow(KV.first)) | |||
566 | AliasMap[KV.first] = SymbolAliasMapEntry(KV.first, KV.second); | |||
567 | ||||
568 | if (AliasMap.empty()) | |||
569 | return Error::success(); | |||
570 | ||||
571 | // Define the re-exports. | |||
572 | return JD.define(reexports(SourceJD, AliasMap, SourceJDLookupFlags)); | |||
573 | } | |||
574 | ||||
575 | LookupState::LookupState(std::unique_ptr<InProgressLookupState> IPLS) | |||
576 | : IPLS(std::move(IPLS)) {} | |||
577 | ||||
578 | void LookupState::reset(InProgressLookupState *IPLS) { this->IPLS.reset(IPLS); } | |||
579 | ||||
580 | LookupState::LookupState() = default; | |||
581 | LookupState::LookupState(LookupState &&) = default; | |||
582 | LookupState &LookupState::operator=(LookupState &&) = default; | |||
583 | LookupState::~LookupState() = default; | |||
584 | ||||
585 | void LookupState::continueLookup(Error Err) { | |||
586 | assert(IPLS && "Cannot call continueLookup on empty LookupState")(static_cast <bool> (IPLS && "Cannot call continueLookup on empty LookupState" ) ? void (0) : __assert_fail ("IPLS && \"Cannot call continueLookup on empty LookupState\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 586, __extension__ __PRETTY_FUNCTION__)); | |||
587 | auto &ES = IPLS->SearchOrder.begin()->first->getExecutionSession(); | |||
588 | ES.OL_applyQueryPhase1(std::move(IPLS), std::move(Err)); | |||
589 | } | |||
590 | ||||
591 | DefinitionGenerator::~DefinitionGenerator() {} | |||
592 | ||||
593 | Error JITDylib::clear() { | |||
594 | std::vector<ResourceTrackerSP> TrackersToRemove; | |||
595 | ES.runSessionLocked([&]() { | |||
596 | for (auto &KV : TrackerSymbols) | |||
597 | TrackersToRemove.push_back(KV.first); | |||
598 | TrackersToRemove.push_back(getDefaultResourceTracker()); | |||
599 | }); | |||
600 | ||||
601 | Error Err = Error::success(); | |||
602 | for (auto &RT : TrackersToRemove) | |||
603 | Err = joinErrors(std::move(Err), RT->remove()); | |||
604 | return Err; | |||
605 | } | |||
606 | ||||
607 | ResourceTrackerSP JITDylib::getDefaultResourceTracker() { | |||
608 | return ES.runSessionLocked([this] { | |||
609 | if (!DefaultTracker) | |||
610 | DefaultTracker = new ResourceTracker(this); | |||
611 | return DefaultTracker; | |||
612 | }); | |||
613 | } | |||
614 | ||||
615 | ResourceTrackerSP JITDylib::createResourceTracker() { | |||
616 | return ES.runSessionLocked([this] { | |||
617 | ResourceTrackerSP RT = new ResourceTracker(this); | |||
618 | return RT; | |||
619 | }); | |||
620 | } | |||
621 | ||||
622 | void JITDylib::removeGenerator(DefinitionGenerator &G) { | |||
623 | std::lock_guard<std::mutex> Lock(GeneratorsMutex); | |||
624 | auto I = llvm::find_if(DefGenerators, | |||
625 | [&](const std::shared_ptr<DefinitionGenerator> &H) { | |||
626 | return H.get() == &G; | |||
627 | }); | |||
628 | assert(I != DefGenerators.end() && "Generator not found")(static_cast <bool> (I != DefGenerators.end() && "Generator not found") ? void (0) : __assert_fail ("I != DefGenerators.end() && \"Generator not found\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 628, __extension__ __PRETTY_FUNCTION__)); | |||
629 | DefGenerators.erase(I); | |||
630 | } | |||
631 | ||||
632 | Expected<SymbolFlagsMap> | |||
633 | JITDylib::defineMaterializing(SymbolFlagsMap SymbolFlags) { | |||
634 | ||||
635 | return ES.runSessionLocked([&]() -> Expected<SymbolFlagsMap> { | |||
636 | std::vector<SymbolTable::iterator> AddedSyms; | |||
637 | std::vector<SymbolFlagsMap::iterator> RejectedWeakDefs; | |||
638 | ||||
639 | for (auto SFItr = SymbolFlags.begin(), SFEnd = SymbolFlags.end(); | |||
640 | SFItr != SFEnd; ++SFItr) { | |||
641 | ||||
642 | auto &Name = SFItr->first; | |||
643 | auto &Flags = SFItr->second; | |||
644 | ||||
645 | auto EntryItr = Symbols.find(Name); | |||
646 | ||||
647 | // If the entry already exists... | |||
648 | if (EntryItr != Symbols.end()) { | |||
649 | ||||
650 | // If this is a strong definition then error out. | |||
651 | if (!Flags.isWeak()) { | |||
652 | // Remove any symbols already added. | |||
653 | for (auto &SI : AddedSyms) | |||
654 | Symbols.erase(SI); | |||
655 | ||||
656 | // FIXME: Return all duplicates. | |||
657 | return make_error<DuplicateDefinition>(std::string(*Name)); | |||
658 | } | |||
659 | ||||
660 | // Otherwise just make a note to discard this symbol after the loop. | |||
661 | RejectedWeakDefs.push_back(SFItr); | |||
662 | continue; | |||
663 | } else | |||
664 | EntryItr = | |||
665 | Symbols.insert(std::make_pair(Name, SymbolTableEntry(Flags))).first; | |||
666 | ||||
667 | AddedSyms.push_back(EntryItr); | |||
668 | EntryItr->second.setState(SymbolState::Materializing); | |||
669 | } | |||
670 | ||||
671 | // Remove any rejected weak definitions from the SymbolFlags map. | |||
672 | while (!RejectedWeakDefs.empty()) { | |||
673 | SymbolFlags.erase(RejectedWeakDefs.back()); | |||
674 | RejectedWeakDefs.pop_back(); | |||
675 | } | |||
676 | ||||
677 | return SymbolFlags; | |||
678 | }); | |||
679 | } | |||
680 | ||||
681 | Error JITDylib::replace(MaterializationResponsibility &FromMR, | |||
682 | std::unique_ptr<MaterializationUnit> MU) { | |||
683 | assert(MU != nullptr && "Can not replace with a null MaterializationUnit")(static_cast <bool> (MU != nullptr && "Can not replace with a null MaterializationUnit" ) ? void (0) : __assert_fail ("MU != nullptr && \"Can not replace with a null MaterializationUnit\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 683, __extension__ __PRETTY_FUNCTION__)); | |||
684 | std::unique_ptr<MaterializationUnit> MustRunMU; | |||
685 | std::unique_ptr<MaterializationResponsibility> MustRunMR; | |||
686 | ||||
687 | auto Err = | |||
688 | ES.runSessionLocked([&, this]() -> Error { | |||
689 | auto RT = getTracker(FromMR); | |||
690 | ||||
691 | if (RT->isDefunct()) | |||
692 | return make_error<ResourceTrackerDefunct>(std::move(RT)); | |||
693 | ||||
694 | #ifndef NDEBUG | |||
695 | for (auto &KV : MU->getSymbols()) { | |||
696 | auto SymI = Symbols.find(KV.first); | |||
697 | assert(SymI != Symbols.end() && "Replacing unknown symbol")(static_cast <bool> (SymI != Symbols.end() && "Replacing unknown symbol" ) ? void (0) : __assert_fail ("SymI != Symbols.end() && \"Replacing unknown symbol\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 697, __extension__ __PRETTY_FUNCTION__)); | |||
698 | assert(SymI->second.getState() == SymbolState::Materializing &&(static_cast <bool> (SymI->second.getState() == SymbolState ::Materializing && "Can not replace a symbol that ha is not materializing" ) ? void (0) : __assert_fail ("SymI->second.getState() == SymbolState::Materializing && \"Can not replace a symbol that ha is not materializing\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 699, __extension__ __PRETTY_FUNCTION__)) | |||
699 | "Can not replace a symbol that ha is not materializing")(static_cast <bool> (SymI->second.getState() == SymbolState ::Materializing && "Can not replace a symbol that ha is not materializing" ) ? void (0) : __assert_fail ("SymI->second.getState() == SymbolState::Materializing && \"Can not replace a symbol that ha is not materializing\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 699, __extension__ __PRETTY_FUNCTION__)); | |||
700 | assert(!SymI->second.hasMaterializerAttached() &&(static_cast <bool> (!SymI->second.hasMaterializerAttached () && "Symbol should not have materializer attached already" ) ? void (0) : __assert_fail ("!SymI->second.hasMaterializerAttached() && \"Symbol should not have materializer attached already\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 701, __extension__ __PRETTY_FUNCTION__)) | |||
701 | "Symbol should not have materializer attached already")(static_cast <bool> (!SymI->second.hasMaterializerAttached () && "Symbol should not have materializer attached already" ) ? void (0) : __assert_fail ("!SymI->second.hasMaterializerAttached() && \"Symbol should not have materializer attached already\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 701, __extension__ __PRETTY_FUNCTION__)); | |||
702 | assert(UnmaterializedInfos.count(KV.first) == 0 &&(static_cast <bool> (UnmaterializedInfos.count(KV.first ) == 0 && "Symbol being replaced should have no UnmaterializedInfo" ) ? void (0) : __assert_fail ("UnmaterializedInfos.count(KV.first) == 0 && \"Symbol being replaced should have no UnmaterializedInfo\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 703, __extension__ __PRETTY_FUNCTION__)) | |||
703 | "Symbol being replaced should have no UnmaterializedInfo")(static_cast <bool> (UnmaterializedInfos.count(KV.first ) == 0 && "Symbol being replaced should have no UnmaterializedInfo" ) ? void (0) : __assert_fail ("UnmaterializedInfos.count(KV.first) == 0 && \"Symbol being replaced should have no UnmaterializedInfo\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 703, __extension__ __PRETTY_FUNCTION__)); | |||
704 | } | |||
705 | #endif // NDEBUG | |||
706 | ||||
707 | // If the tracker is defunct we need to bail out immediately. | |||
708 | ||||
709 | // If any symbol has pending queries against it then we need to | |||
710 | // materialize MU immediately. | |||
711 | for (auto &KV : MU->getSymbols()) { | |||
712 | auto MII = MaterializingInfos.find(KV.first); | |||
713 | if (MII != MaterializingInfos.end()) { | |||
714 | if (MII->second.hasQueriesPending()) { | |||
715 | MustRunMR = ES.createMaterializationResponsibility( | |||
716 | *RT, std::move(MU->SymbolFlags), std::move(MU->InitSymbol)); | |||
717 | MustRunMU = std::move(MU); | |||
718 | return Error::success(); | |||
719 | } | |||
720 | } | |||
721 | } | |||
722 | ||||
723 | // Otherwise, make MU responsible for all the symbols. | |||
724 | auto RTI = MRTrackers.find(&FromMR); | |||
725 | assert(RTI != MRTrackers.end() && "No tracker for FromMR")(static_cast <bool> (RTI != MRTrackers.end() && "No tracker for FromMR") ? void (0) : __assert_fail ("RTI != MRTrackers.end() && \"No tracker for FromMR\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 725, __extension__ __PRETTY_FUNCTION__)); | |||
726 | auto UMI = | |||
727 | std::make_shared<UnmaterializedInfo>(std::move(MU), RTI->second); | |||
728 | for (auto &KV : UMI->MU->getSymbols()) { | |||
729 | auto SymI = Symbols.find(KV.first); | |||
730 | assert(SymI->second.getState() == SymbolState::Materializing &&(static_cast <bool> (SymI->second.getState() == SymbolState ::Materializing && "Can not replace a symbol that is not materializing" ) ? void (0) : __assert_fail ("SymI->second.getState() == SymbolState::Materializing && \"Can not replace a symbol that is not materializing\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 731, __extension__ __PRETTY_FUNCTION__)) | |||
731 | "Can not replace a symbol that is not materializing")(static_cast <bool> (SymI->second.getState() == SymbolState ::Materializing && "Can not replace a symbol that is not materializing" ) ? void (0) : __assert_fail ("SymI->second.getState() == SymbolState::Materializing && \"Can not replace a symbol that is not materializing\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 731, __extension__ __PRETTY_FUNCTION__)); | |||
732 | assert(!SymI->second.hasMaterializerAttached() &&(static_cast <bool> (!SymI->second.hasMaterializerAttached () && "Can not replace a symbol that has a materializer attached" ) ? void (0) : __assert_fail ("!SymI->second.hasMaterializerAttached() && \"Can not replace a symbol that has a materializer attached\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 733, __extension__ __PRETTY_FUNCTION__)) | |||
733 | "Can not replace a symbol that has a materializer attached")(static_cast <bool> (!SymI->second.hasMaterializerAttached () && "Can not replace a symbol that has a materializer attached" ) ? void (0) : __assert_fail ("!SymI->second.hasMaterializerAttached() && \"Can not replace a symbol that has a materializer attached\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 733, __extension__ __PRETTY_FUNCTION__)); | |||
734 | assert(UnmaterializedInfos.count(KV.first) == 0 &&(static_cast <bool> (UnmaterializedInfos.count(KV.first ) == 0 && "Unexpected materializer entry in map") ? void (0) : __assert_fail ("UnmaterializedInfos.count(KV.first) == 0 && \"Unexpected materializer entry in map\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 735, __extension__ __PRETTY_FUNCTION__)) | |||
735 | "Unexpected materializer entry in map")(static_cast <bool> (UnmaterializedInfos.count(KV.first ) == 0 && "Unexpected materializer entry in map") ? void (0) : __assert_fail ("UnmaterializedInfos.count(KV.first) == 0 && \"Unexpected materializer entry in map\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 735, __extension__ __PRETTY_FUNCTION__)); | |||
736 | SymI->second.setAddress(SymI->second.getAddress()); | |||
737 | SymI->second.setMaterializerAttached(true); | |||
738 | ||||
739 | auto &UMIEntry = UnmaterializedInfos[KV.first]; | |||
740 | assert((!UMIEntry || !UMIEntry->MU) &&(static_cast <bool> ((!UMIEntry || !UMIEntry->MU) && "Replacing symbol with materializer still attached") ? void ( 0) : __assert_fail ("(!UMIEntry || !UMIEntry->MU) && \"Replacing symbol with materializer still attached\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 741, __extension__ __PRETTY_FUNCTION__)) | |||
741 | "Replacing symbol with materializer still attached")(static_cast <bool> ((!UMIEntry || !UMIEntry->MU) && "Replacing symbol with materializer still attached") ? void ( 0) : __assert_fail ("(!UMIEntry || !UMIEntry->MU) && \"Replacing symbol with materializer still attached\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 741, __extension__ __PRETTY_FUNCTION__)); | |||
742 | UMIEntry = UMI; | |||
743 | } | |||
744 | ||||
745 | return Error::success(); | |||
746 | }); | |||
747 | ||||
748 | if (Err) | |||
749 | return Err; | |||
750 | ||||
751 | if (MustRunMU) { | |||
752 | assert(MustRunMR && "MustRunMU set implies MustRunMR set")(static_cast <bool> (MustRunMR && "MustRunMU set implies MustRunMR set" ) ? void (0) : __assert_fail ("MustRunMR && \"MustRunMU set implies MustRunMR set\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 752, __extension__ __PRETTY_FUNCTION__)); | |||
753 | ES.dispatchMaterialization(std::move(MustRunMU), std::move(MustRunMR)); | |||
754 | } else { | |||
755 | assert(!MustRunMR && "MustRunMU unset implies MustRunMR unset")(static_cast <bool> (!MustRunMR && "MustRunMU unset implies MustRunMR unset" ) ? void (0) : __assert_fail ("!MustRunMR && \"MustRunMU unset implies MustRunMR unset\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 755, __extension__ __PRETTY_FUNCTION__)); | |||
756 | } | |||
757 | ||||
758 | return Error::success(); | |||
759 | } | |||
760 | ||||
761 | Expected<std::unique_ptr<MaterializationResponsibility>> | |||
762 | JITDylib::delegate(MaterializationResponsibility &FromMR, | |||
763 | SymbolFlagsMap SymbolFlags, SymbolStringPtr InitSymbol) { | |||
764 | ||||
765 | return ES.runSessionLocked( | |||
766 | [&]() -> Expected<std::unique_ptr<MaterializationResponsibility>> { | |||
767 | auto RT = getTracker(FromMR); | |||
768 | ||||
769 | if (RT->isDefunct()) | |||
770 | return make_error<ResourceTrackerDefunct>(std::move(RT)); | |||
771 | ||||
772 | return ES.createMaterializationResponsibility( | |||
773 | *RT, std::move(SymbolFlags), std::move(InitSymbol)); | |||
774 | }); | |||
775 | } | |||
776 | ||||
777 | SymbolNameSet | |||
778 | JITDylib::getRequestedSymbols(const SymbolFlagsMap &SymbolFlags) const { | |||
779 | return ES.runSessionLocked([&]() { | |||
780 | SymbolNameSet RequestedSymbols; | |||
781 | ||||
782 | for (auto &KV : SymbolFlags) { | |||
783 | assert(Symbols.count(KV.first) && "JITDylib does not cover this symbol?")(static_cast <bool> (Symbols.count(KV.first) && "JITDylib does not cover this symbol?") ? void (0) : __assert_fail ("Symbols.count(KV.first) && \"JITDylib does not cover this symbol?\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 783, __extension__ __PRETTY_FUNCTION__)); | |||
784 | assert(Symbols.find(KV.first)->second.getState() !=(static_cast <bool> (Symbols.find(KV.first)->second. getState() != SymbolState::NeverSearched && Symbols.find (KV.first)->second.getState() != SymbolState::Ready && "getRequestedSymbols can only be called for symbols that have " "started materializing") ? void (0) : __assert_fail ("Symbols.find(KV.first)->second.getState() != SymbolState::NeverSearched && Symbols.find(KV.first)->second.getState() != SymbolState::Ready && \"getRequestedSymbols can only be called for symbols that have \" \"started materializing\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 788, __extension__ __PRETTY_FUNCTION__)) | |||
785 | SymbolState::NeverSearched &&(static_cast <bool> (Symbols.find(KV.first)->second. getState() != SymbolState::NeverSearched && Symbols.find (KV.first)->second.getState() != SymbolState::Ready && "getRequestedSymbols can only be called for symbols that have " "started materializing") ? void (0) : __assert_fail ("Symbols.find(KV.first)->second.getState() != SymbolState::NeverSearched && Symbols.find(KV.first)->second.getState() != SymbolState::Ready && \"getRequestedSymbols can only be called for symbols that have \" \"started materializing\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 788, __extension__ __PRETTY_FUNCTION__)) | |||
786 | Symbols.find(KV.first)->second.getState() != SymbolState::Ready &&(static_cast <bool> (Symbols.find(KV.first)->second. getState() != SymbolState::NeverSearched && Symbols.find (KV.first)->second.getState() != SymbolState::Ready && "getRequestedSymbols can only be called for symbols that have " "started materializing") ? void (0) : __assert_fail ("Symbols.find(KV.first)->second.getState() != SymbolState::NeverSearched && Symbols.find(KV.first)->second.getState() != SymbolState::Ready && \"getRequestedSymbols can only be called for symbols that have \" \"started materializing\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 788, __extension__ __PRETTY_FUNCTION__)) | |||
787 | "getRequestedSymbols can only be called for symbols that have "(static_cast <bool> (Symbols.find(KV.first)->second. getState() != SymbolState::NeverSearched && Symbols.find (KV.first)->second.getState() != SymbolState::Ready && "getRequestedSymbols can only be called for symbols that have " "started materializing") ? void (0) : __assert_fail ("Symbols.find(KV.first)->second.getState() != SymbolState::NeverSearched && Symbols.find(KV.first)->second.getState() != SymbolState::Ready && \"getRequestedSymbols can only be called for symbols that have \" \"started materializing\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 788, __extension__ __PRETTY_FUNCTION__)) | |||
788 | "started materializing")(static_cast <bool> (Symbols.find(KV.first)->second. getState() != SymbolState::NeverSearched && Symbols.find (KV.first)->second.getState() != SymbolState::Ready && "getRequestedSymbols can only be called for symbols that have " "started materializing") ? void (0) : __assert_fail ("Symbols.find(KV.first)->second.getState() != SymbolState::NeverSearched && Symbols.find(KV.first)->second.getState() != SymbolState::Ready && \"getRequestedSymbols can only be called for symbols that have \" \"started materializing\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 788, __extension__ __PRETTY_FUNCTION__)); | |||
789 | auto I = MaterializingInfos.find(KV.first); | |||
790 | if (I == MaterializingInfos.end()) | |||
791 | continue; | |||
792 | ||||
793 | if (I->second.hasQueriesPending()) | |||
794 | RequestedSymbols.insert(KV.first); | |||
795 | } | |||
796 | ||||
797 | return RequestedSymbols; | |||
798 | }); | |||
799 | } | |||
800 | ||||
801 | void JITDylib::addDependencies(const SymbolStringPtr &Name, | |||
802 | const SymbolDependenceMap &Dependencies) { | |||
803 | ES.runSessionLocked([&]() { | |||
804 | assert(Symbols.count(Name) && "Name not in symbol table")(static_cast <bool> (Symbols.count(Name) && "Name not in symbol table" ) ? void (0) : __assert_fail ("Symbols.count(Name) && \"Name not in symbol table\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 804, __extension__ __PRETTY_FUNCTION__)); | |||
805 | assert(Symbols[Name].getState() < SymbolState::Emitted &&(static_cast <bool> (Symbols[Name].getState() < SymbolState ::Emitted && "Can not add dependencies for a symbol that is not materializing" ) ? void (0) : __assert_fail ("Symbols[Name].getState() < SymbolState::Emitted && \"Can not add dependencies for a symbol that is not materializing\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 806, __extension__ __PRETTY_FUNCTION__)) | |||
806 | "Can not add dependencies for a symbol that is not materializing")(static_cast <bool> (Symbols[Name].getState() < SymbolState ::Emitted && "Can not add dependencies for a symbol that is not materializing" ) ? void (0) : __assert_fail ("Symbols[Name].getState() < SymbolState::Emitted && \"Can not add dependencies for a symbol that is not materializing\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 806, __extension__ __PRETTY_FUNCTION__)); | |||
807 | ||||
808 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << getName() << " adding dependencies for " << *Name << ": " << Dependencies << "\n"; }; } } while (false) | |||
809 | dbgs() << "In " << getName() << " adding dependencies for " << *Namedo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << getName() << " adding dependencies for " << *Name << ": " << Dependencies << "\n"; }; } } while (false) | |||
810 | << ": " << Dependencies << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << getName() << " adding dependencies for " << *Name << ": " << Dependencies << "\n"; }; } } while (false) | |||
811 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << getName() << " adding dependencies for " << *Name << ": " << Dependencies << "\n"; }; } } while (false); | |||
812 | ||||
813 | // If Name is already in an error state then just bail out. | |||
814 | if (Symbols[Name].getFlags().hasError()) | |||
815 | return; | |||
816 | ||||
817 | auto &MI = MaterializingInfos[Name]; | |||
818 | assert(Symbols[Name].getState() != SymbolState::Emitted &&(static_cast <bool> (Symbols[Name].getState() != SymbolState ::Emitted && "Can not add dependencies to an emitted symbol" ) ? void (0) : __assert_fail ("Symbols[Name].getState() != SymbolState::Emitted && \"Can not add dependencies to an emitted symbol\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 819, __extension__ __PRETTY_FUNCTION__)) | |||
819 | "Can not add dependencies to an emitted symbol")(static_cast <bool> (Symbols[Name].getState() != SymbolState ::Emitted && "Can not add dependencies to an emitted symbol" ) ? void (0) : __assert_fail ("Symbols[Name].getState() != SymbolState::Emitted && \"Can not add dependencies to an emitted symbol\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 819, __extension__ __PRETTY_FUNCTION__)); | |||
820 | ||||
821 | bool DependsOnSymbolInErrorState = false; | |||
822 | ||||
823 | // Register dependencies, record whether any depenendency is in the error | |||
824 | // state. | |||
825 | for (auto &KV : Dependencies) { | |||
826 | assert(KV.first && "Null JITDylib in dependency?")(static_cast <bool> (KV.first && "Null JITDylib in dependency?" ) ? void (0) : __assert_fail ("KV.first && \"Null JITDylib in dependency?\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 826, __extension__ __PRETTY_FUNCTION__)); | |||
827 | auto &OtherJITDylib = *KV.first; | |||
828 | auto &DepsOnOtherJITDylib = MI.UnemittedDependencies[&OtherJITDylib]; | |||
829 | ||||
830 | for (auto &OtherSymbol : KV.second) { | |||
831 | ||||
832 | // Check the sym entry for the dependency. | |||
833 | auto OtherSymI = OtherJITDylib.Symbols.find(OtherSymbol); | |||
834 | ||||
835 | // Assert that this symbol exists and has not reached the ready state | |||
836 | // already. | |||
837 | assert(OtherSymI != OtherJITDylib.Symbols.end() &&(static_cast <bool> (OtherSymI != OtherJITDylib.Symbols .end() && "Dependency on unknown symbol") ? void (0) : __assert_fail ("OtherSymI != OtherJITDylib.Symbols.end() && \"Dependency on unknown symbol\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 838, __extension__ __PRETTY_FUNCTION__)) | |||
838 | "Dependency on unknown symbol")(static_cast <bool> (OtherSymI != OtherJITDylib.Symbols .end() && "Dependency on unknown symbol") ? void (0) : __assert_fail ("OtherSymI != OtherJITDylib.Symbols.end() && \"Dependency on unknown symbol\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 838, __extension__ __PRETTY_FUNCTION__)); | |||
839 | ||||
840 | auto &OtherSymEntry = OtherSymI->second; | |||
841 | ||||
842 | // If the other symbol is already in the Ready state then there's no | |||
843 | // dependency to add. | |||
844 | if (OtherSymEntry.getState() == SymbolState::Ready) | |||
845 | continue; | |||
846 | ||||
847 | // If the dependency is in an error state then note this and continue, | |||
848 | // we will move this symbol to the error state below. | |||
849 | if (OtherSymEntry.getFlags().hasError()) { | |||
850 | DependsOnSymbolInErrorState = true; | |||
851 | continue; | |||
852 | } | |||
853 | ||||
854 | // If the dependency was not in the error state then add it to | |||
855 | // our list of dependencies. | |||
856 | auto &OtherMI = OtherJITDylib.MaterializingInfos[OtherSymbol]; | |||
857 | ||||
858 | if (OtherSymEntry.getState() == SymbolState::Emitted) | |||
859 | transferEmittedNodeDependencies(MI, Name, OtherMI); | |||
860 | else if (&OtherJITDylib != this || OtherSymbol != Name) { | |||
861 | OtherMI.Dependants[this].insert(Name); | |||
862 | DepsOnOtherJITDylib.insert(OtherSymbol); | |||
863 | } | |||
864 | } | |||
865 | ||||
866 | if (DepsOnOtherJITDylib.empty()) | |||
867 | MI.UnemittedDependencies.erase(&OtherJITDylib); | |||
868 | } | |||
869 | ||||
870 | // If this symbol dependended on any symbols in the error state then move | |||
871 | // this symbol to the error state too. | |||
872 | if (DependsOnSymbolInErrorState) | |||
873 | Symbols[Name].setFlags(Symbols[Name].getFlags() | | |||
874 | JITSymbolFlags::HasError); | |||
875 | }); | |||
876 | } | |||
877 | ||||
878 | Error JITDylib::resolve(MaterializationResponsibility &MR, | |||
879 | const SymbolMap &Resolved) { | |||
880 | AsynchronousSymbolQuerySet CompletedQueries; | |||
881 | ||||
882 | if (auto Err = ES.runSessionLocked([&, this]() -> Error { | |||
883 | auto RTI = MRTrackers.find(&MR); | |||
884 | assert(RTI != MRTrackers.end() && "No resource tracker for MR?")(static_cast <bool> (RTI != MRTrackers.end() && "No resource tracker for MR?") ? void (0) : __assert_fail ("RTI != MRTrackers.end() && \"No resource tracker for MR?\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 884, __extension__ __PRETTY_FUNCTION__)); | |||
885 | if (RTI->second->isDefunct()) | |||
886 | return make_error<ResourceTrackerDefunct>(RTI->second); | |||
887 | ||||
888 | struct WorklistEntry { | |||
889 | SymbolTable::iterator SymI; | |||
890 | JITEvaluatedSymbol ResolvedSym; | |||
891 | }; | |||
892 | ||||
893 | SymbolNameSet SymbolsInErrorState; | |||
894 | std::vector<WorklistEntry> Worklist; | |||
895 | Worklist.reserve(Resolved.size()); | |||
896 | ||||
897 | // Build worklist and check for any symbols in the error state. | |||
898 | for (const auto &KV : Resolved) { | |||
899 | ||||
900 | assert(!KV.second.getFlags().hasError() &&(static_cast <bool> (!KV.second.getFlags().hasError() && "Resolution result can not have error flag set") ? void (0) : __assert_fail ("!KV.second.getFlags().hasError() && \"Resolution result can not have error flag set\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 901, __extension__ __PRETTY_FUNCTION__)) | |||
901 | "Resolution result can not have error flag set")(static_cast <bool> (!KV.second.getFlags().hasError() && "Resolution result can not have error flag set") ? void (0) : __assert_fail ("!KV.second.getFlags().hasError() && \"Resolution result can not have error flag set\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 901, __extension__ __PRETTY_FUNCTION__)); | |||
902 | ||||
903 | auto SymI = Symbols.find(KV.first); | |||
904 | ||||
905 | assert(SymI != Symbols.end() && "Symbol not found")(static_cast <bool> (SymI != Symbols.end() && "Symbol not found" ) ? void (0) : __assert_fail ("SymI != Symbols.end() && \"Symbol not found\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 905, __extension__ __PRETTY_FUNCTION__)); | |||
906 | assert(!SymI->second.hasMaterializerAttached() &&(static_cast <bool> (!SymI->second.hasMaterializerAttached () && "Resolving symbol with materializer attached?") ? void (0) : __assert_fail ("!SymI->second.hasMaterializerAttached() && \"Resolving symbol with materializer attached?\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 907, __extension__ __PRETTY_FUNCTION__)) | |||
907 | "Resolving symbol with materializer attached?")(static_cast <bool> (!SymI->second.hasMaterializerAttached () && "Resolving symbol with materializer attached?") ? void (0) : __assert_fail ("!SymI->second.hasMaterializerAttached() && \"Resolving symbol with materializer attached?\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 907, __extension__ __PRETTY_FUNCTION__)); | |||
908 | assert(SymI->second.getState() == SymbolState::Materializing &&(static_cast <bool> (SymI->second.getState() == SymbolState ::Materializing && "Symbol should be materializing") ? void (0) : __assert_fail ("SymI->second.getState() == SymbolState::Materializing && \"Symbol should be materializing\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 909, __extension__ __PRETTY_FUNCTION__)) | |||
909 | "Symbol should be materializing")(static_cast <bool> (SymI->second.getState() == SymbolState ::Materializing && "Symbol should be materializing") ? void (0) : __assert_fail ("SymI->second.getState() == SymbolState::Materializing && \"Symbol should be materializing\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 909, __extension__ __PRETTY_FUNCTION__)); | |||
910 | assert(SymI->second.getAddress() == 0 &&(static_cast <bool> (SymI->second.getAddress() == 0 && "Symbol has already been resolved") ? void (0) : __assert_fail ("SymI->second.getAddress() == 0 && \"Symbol has already been resolved\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 911, __extension__ __PRETTY_FUNCTION__)) | |||
911 | "Symbol has already been resolved")(static_cast <bool> (SymI->second.getAddress() == 0 && "Symbol has already been resolved") ? void (0) : __assert_fail ("SymI->second.getAddress() == 0 && \"Symbol has already been resolved\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 911, __extension__ __PRETTY_FUNCTION__)); | |||
912 | ||||
913 | if (SymI->second.getFlags().hasError()) | |||
914 | SymbolsInErrorState.insert(KV.first); | |||
915 | else { | |||
916 | auto Flags = KV.second.getFlags(); | |||
917 | Flags &= ~(JITSymbolFlags::Weak | JITSymbolFlags::Common); | |||
918 | assert(Flags ==(static_cast <bool> (Flags == (SymI->second.getFlags () & ~(JITSymbolFlags::Weak | JITSymbolFlags::Common)) && "Resolved flags should match the declared flags") ? void (0) : __assert_fail ("Flags == (SymI->second.getFlags() & ~(JITSymbolFlags::Weak | JITSymbolFlags::Common)) && \"Resolved flags should match the declared flags\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 921, __extension__ __PRETTY_FUNCTION__)) | |||
919 | (SymI->second.getFlags() &(static_cast <bool> (Flags == (SymI->second.getFlags () & ~(JITSymbolFlags::Weak | JITSymbolFlags::Common)) && "Resolved flags should match the declared flags") ? void (0) : __assert_fail ("Flags == (SymI->second.getFlags() & ~(JITSymbolFlags::Weak | JITSymbolFlags::Common)) && \"Resolved flags should match the declared flags\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 921, __extension__ __PRETTY_FUNCTION__)) | |||
920 | ~(JITSymbolFlags::Weak | JITSymbolFlags::Common)) &&(static_cast <bool> (Flags == (SymI->second.getFlags () & ~(JITSymbolFlags::Weak | JITSymbolFlags::Common)) && "Resolved flags should match the declared flags") ? void (0) : __assert_fail ("Flags == (SymI->second.getFlags() & ~(JITSymbolFlags::Weak | JITSymbolFlags::Common)) && \"Resolved flags should match the declared flags\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 921, __extension__ __PRETTY_FUNCTION__)) | |||
921 | "Resolved flags should match the declared flags")(static_cast <bool> (Flags == (SymI->second.getFlags () & ~(JITSymbolFlags::Weak | JITSymbolFlags::Common)) && "Resolved flags should match the declared flags") ? void (0) : __assert_fail ("Flags == (SymI->second.getFlags() & ~(JITSymbolFlags::Weak | JITSymbolFlags::Common)) && \"Resolved flags should match the declared flags\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 921, __extension__ __PRETTY_FUNCTION__)); | |||
922 | ||||
923 | Worklist.push_back( | |||
924 | {SymI, JITEvaluatedSymbol(KV.second.getAddress(), Flags)}); | |||
925 | } | |||
926 | } | |||
927 | ||||
928 | // If any symbols were in the error state then bail out. | |||
929 | if (!SymbolsInErrorState.empty()) { | |||
930 | auto FailedSymbolsDepMap = std::make_shared<SymbolDependenceMap>(); | |||
931 | (*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState); | |||
932 | return make_error<FailedToMaterialize>( | |||
933 | std::move(FailedSymbolsDepMap)); | |||
934 | } | |||
935 | ||||
936 | while (!Worklist.empty()) { | |||
937 | auto SymI = Worklist.back().SymI; | |||
938 | auto ResolvedSym = Worklist.back().ResolvedSym; | |||
939 | Worklist.pop_back(); | |||
940 | ||||
941 | auto &Name = SymI->first; | |||
942 | ||||
943 | // Resolved symbols can not be weak: discard the weak flag. | |||
944 | JITSymbolFlags ResolvedFlags = ResolvedSym.getFlags(); | |||
945 | SymI->second.setAddress(ResolvedSym.getAddress()); | |||
946 | SymI->second.setFlags(ResolvedFlags); | |||
947 | SymI->second.setState(SymbolState::Resolved); | |||
948 | ||||
949 | auto MII = MaterializingInfos.find(Name); | |||
950 | if (MII == MaterializingInfos.end()) | |||
951 | continue; | |||
952 | ||||
953 | auto &MI = MII->second; | |||
954 | for (auto &Q : MI.takeQueriesMeeting(SymbolState::Resolved)) { | |||
955 | Q->notifySymbolMetRequiredState(Name, ResolvedSym); | |||
956 | Q->removeQueryDependence(*this, Name); | |||
957 | if (Q->isComplete()) | |||
958 | CompletedQueries.insert(std::move(Q)); | |||
959 | } | |||
960 | } | |||
961 | ||||
962 | return Error::success(); | |||
963 | })) | |||
964 | return Err; | |||
965 | ||||
966 | // Otherwise notify all the completed queries. | |||
967 | for (auto &Q : CompletedQueries) { | |||
968 | assert(Q->isComplete() && "Q not completed")(static_cast <bool> (Q->isComplete() && "Q not completed" ) ? void (0) : __assert_fail ("Q->isComplete() && \"Q not completed\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 968, __extension__ __PRETTY_FUNCTION__)); | |||
969 | Q->handleComplete(); | |||
970 | } | |||
971 | ||||
972 | return Error::success(); | |||
973 | } | |||
974 | ||||
975 | Error JITDylib::emit(MaterializationResponsibility &MR, | |||
976 | const SymbolFlagsMap &Emitted) { | |||
977 | AsynchronousSymbolQuerySet CompletedQueries; | |||
978 | DenseMap<JITDylib *, SymbolNameVector> ReadySymbols; | |||
979 | ||||
980 | if (auto Err = ES.runSessionLocked([&, this]() -> Error { | |||
981 | auto RTI = MRTrackers.find(&MR); | |||
982 | assert(RTI != MRTrackers.end() && "No resource tracker for MR?")(static_cast <bool> (RTI != MRTrackers.end() && "No resource tracker for MR?") ? void (0) : __assert_fail ("RTI != MRTrackers.end() && \"No resource tracker for MR?\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 982, __extension__ __PRETTY_FUNCTION__)); | |||
983 | if (RTI->second->isDefunct()) | |||
984 | return make_error<ResourceTrackerDefunct>(RTI->second); | |||
985 | ||||
986 | SymbolNameSet SymbolsInErrorState; | |||
987 | std::vector<SymbolTable::iterator> Worklist; | |||
988 | ||||
989 | // Scan to build worklist, record any symbols in the erorr state. | |||
990 | for (const auto &KV : Emitted) { | |||
991 | auto &Name = KV.first; | |||
992 | ||||
993 | auto SymI = Symbols.find(Name); | |||
994 | assert(SymI != Symbols.end() && "No symbol table entry for Name")(static_cast <bool> (SymI != Symbols.end() && "No symbol table entry for Name" ) ? void (0) : __assert_fail ("SymI != Symbols.end() && \"No symbol table entry for Name\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 994, __extension__ __PRETTY_FUNCTION__)); | |||
995 | ||||
996 | if (SymI->second.getFlags().hasError()) | |||
997 | SymbolsInErrorState.insert(Name); | |||
998 | else | |||
999 | Worklist.push_back(SymI); | |||
1000 | } | |||
1001 | ||||
1002 | // If any symbols were in the error state then bail out. | |||
1003 | if (!SymbolsInErrorState.empty()) { | |||
1004 | auto FailedSymbolsDepMap = std::make_shared<SymbolDependenceMap>(); | |||
1005 | (*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState); | |||
1006 | return make_error<FailedToMaterialize>( | |||
1007 | std::move(FailedSymbolsDepMap)); | |||
1008 | } | |||
1009 | ||||
1010 | // Otherwise update dependencies and move to the emitted state. | |||
1011 | while (!Worklist.empty()) { | |||
1012 | auto SymI = Worklist.back(); | |||
1013 | Worklist.pop_back(); | |||
1014 | ||||
1015 | auto &Name = SymI->first; | |||
1016 | auto &SymEntry = SymI->second; | |||
1017 | ||||
1018 | // Move symbol to the emitted state. | |||
1019 | assert(((SymEntry.getFlags().hasMaterializationSideEffectsOnly() &&(static_cast <bool> (((SymEntry.getFlags().hasMaterializationSideEffectsOnly () && SymEntry.getState() == SymbolState::Materializing ) || SymEntry.getState() == SymbolState::Resolved) && "Emitting from state other than Resolved") ? void (0) : __assert_fail ("((SymEntry.getFlags().hasMaterializationSideEffectsOnly() && SymEntry.getState() == SymbolState::Materializing) || SymEntry.getState() == SymbolState::Resolved) && \"Emitting from state other than Resolved\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1022, __extension__ __PRETTY_FUNCTION__)) | |||
1020 | SymEntry.getState() == SymbolState::Materializing) ||(static_cast <bool> (((SymEntry.getFlags().hasMaterializationSideEffectsOnly () && SymEntry.getState() == SymbolState::Materializing ) || SymEntry.getState() == SymbolState::Resolved) && "Emitting from state other than Resolved") ? void (0) : __assert_fail ("((SymEntry.getFlags().hasMaterializationSideEffectsOnly() && SymEntry.getState() == SymbolState::Materializing) || SymEntry.getState() == SymbolState::Resolved) && \"Emitting from state other than Resolved\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1022, __extension__ __PRETTY_FUNCTION__)) | |||
1021 | SymEntry.getState() == SymbolState::Resolved) &&(static_cast <bool> (((SymEntry.getFlags().hasMaterializationSideEffectsOnly () && SymEntry.getState() == SymbolState::Materializing ) || SymEntry.getState() == SymbolState::Resolved) && "Emitting from state other than Resolved") ? void (0) : __assert_fail ("((SymEntry.getFlags().hasMaterializationSideEffectsOnly() && SymEntry.getState() == SymbolState::Materializing) || SymEntry.getState() == SymbolState::Resolved) && \"Emitting from state other than Resolved\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1022, __extension__ __PRETTY_FUNCTION__)) | |||
1022 | "Emitting from state other than Resolved")(static_cast <bool> (((SymEntry.getFlags().hasMaterializationSideEffectsOnly () && SymEntry.getState() == SymbolState::Materializing ) || SymEntry.getState() == SymbolState::Resolved) && "Emitting from state other than Resolved") ? void (0) : __assert_fail ("((SymEntry.getFlags().hasMaterializationSideEffectsOnly() && SymEntry.getState() == SymbolState::Materializing) || SymEntry.getState() == SymbolState::Resolved) && \"Emitting from state other than Resolved\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1022, __extension__ __PRETTY_FUNCTION__)); | |||
1023 | SymEntry.setState(SymbolState::Emitted); | |||
1024 | ||||
1025 | auto MII = MaterializingInfos.find(Name); | |||
1026 | ||||
1027 | // If this symbol has no MaterializingInfo then it's trivially ready. | |||
1028 | // Update its state and continue. | |||
1029 | if (MII == MaterializingInfos.end()) { | |||
1030 | SymEntry.setState(SymbolState::Ready); | |||
1031 | continue; | |||
1032 | } | |||
1033 | ||||
1034 | auto &MI = MII->second; | |||
1035 | ||||
1036 | // For each dependant, transfer this node's emitted dependencies to | |||
1037 | // it. If the dependant node is ready (i.e. has no unemitted | |||
1038 | // dependencies) then notify any pending queries. | |||
1039 | for (auto &KV : MI.Dependants) { | |||
1040 | auto &DependantJD = *KV.first; | |||
1041 | auto &DependantJDReadySymbols = ReadySymbols[&DependantJD]; | |||
1042 | for (auto &DependantName : KV.second) { | |||
1043 | auto DependantMII = | |||
1044 | DependantJD.MaterializingInfos.find(DependantName); | |||
1045 | assert(DependantMII != DependantJD.MaterializingInfos.end() &&(static_cast <bool> (DependantMII != DependantJD.MaterializingInfos .end() && "Dependant should have MaterializingInfo") ? void (0) : __assert_fail ("DependantMII != DependantJD.MaterializingInfos.end() && \"Dependant should have MaterializingInfo\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1046, __extension__ __PRETTY_FUNCTION__)) | |||
1046 | "Dependant should have MaterializingInfo")(static_cast <bool> (DependantMII != DependantJD.MaterializingInfos .end() && "Dependant should have MaterializingInfo") ? void (0) : __assert_fail ("DependantMII != DependantJD.MaterializingInfos.end() && \"Dependant should have MaterializingInfo\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1046, __extension__ __PRETTY_FUNCTION__)); | |||
1047 | ||||
1048 | auto &DependantMI = DependantMII->second; | |||
1049 | ||||
1050 | // Remove the dependant's dependency on this node. | |||
1051 | assert(DependantMI.UnemittedDependencies.count(this) &&(static_cast <bool> (DependantMI.UnemittedDependencies. count(this) && "Dependant does not have an unemitted dependencies record " "for " "this JITDylib") ? void (0) : __assert_fail ("DependantMI.UnemittedDependencies.count(this) && \"Dependant does not have an unemitted dependencies record \" \"for \" \"this JITDylib\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1054, __extension__ __PRETTY_FUNCTION__)) | |||
1052 | "Dependant does not have an unemitted dependencies record "(static_cast <bool> (DependantMI.UnemittedDependencies. count(this) && "Dependant does not have an unemitted dependencies record " "for " "this JITDylib") ? void (0) : __assert_fail ("DependantMI.UnemittedDependencies.count(this) && \"Dependant does not have an unemitted dependencies record \" \"for \" \"this JITDylib\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1054, __extension__ __PRETTY_FUNCTION__)) | |||
1053 | "for "(static_cast <bool> (DependantMI.UnemittedDependencies. count(this) && "Dependant does not have an unemitted dependencies record " "for " "this JITDylib") ? void (0) : __assert_fail ("DependantMI.UnemittedDependencies.count(this) && \"Dependant does not have an unemitted dependencies record \" \"for \" \"this JITDylib\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1054, __extension__ __PRETTY_FUNCTION__)) | |||
1054 | "this JITDylib")(static_cast <bool> (DependantMI.UnemittedDependencies. count(this) && "Dependant does not have an unemitted dependencies record " "for " "this JITDylib") ? void (0) : __assert_fail ("DependantMI.UnemittedDependencies.count(this) && \"Dependant does not have an unemitted dependencies record \" \"for \" \"this JITDylib\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1054, __extension__ __PRETTY_FUNCTION__)); | |||
1055 | assert(DependantMI.UnemittedDependencies[this].count(Name) &&(static_cast <bool> (DependantMI.UnemittedDependencies[ this].count(Name) && "Dependant does not count this symbol as a dependency?" ) ? void (0) : __assert_fail ("DependantMI.UnemittedDependencies[this].count(Name) && \"Dependant does not count this symbol as a dependency?\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1056, __extension__ __PRETTY_FUNCTION__)) | |||
1056 | "Dependant does not count this symbol as a dependency?")(static_cast <bool> (DependantMI.UnemittedDependencies[ this].count(Name) && "Dependant does not count this symbol as a dependency?" ) ? void (0) : __assert_fail ("DependantMI.UnemittedDependencies[this].count(Name) && \"Dependant does not count this symbol as a dependency?\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1056, __extension__ __PRETTY_FUNCTION__)); | |||
1057 | ||||
1058 | DependantMI.UnemittedDependencies[this].erase(Name); | |||
1059 | if (DependantMI.UnemittedDependencies[this].empty()) | |||
1060 | DependantMI.UnemittedDependencies.erase(this); | |||
1061 | ||||
1062 | // Transfer unemitted dependencies from this node to the | |||
1063 | // dependant. | |||
1064 | DependantJD.transferEmittedNodeDependencies(DependantMI, | |||
1065 | DependantName, MI); | |||
1066 | ||||
1067 | auto DependantSymI = DependantJD.Symbols.find(DependantName); | |||
1068 | assert(DependantSymI != DependantJD.Symbols.end() &&(static_cast <bool> (DependantSymI != DependantJD.Symbols .end() && "Dependant has no entry in the Symbols table" ) ? void (0) : __assert_fail ("DependantSymI != DependantJD.Symbols.end() && \"Dependant has no entry in the Symbols table\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1069, __extension__ __PRETTY_FUNCTION__)) | |||
1069 | "Dependant has no entry in the Symbols table")(static_cast <bool> (DependantSymI != DependantJD.Symbols .end() && "Dependant has no entry in the Symbols table" ) ? void (0) : __assert_fail ("DependantSymI != DependantJD.Symbols.end() && \"Dependant has no entry in the Symbols table\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1069, __extension__ __PRETTY_FUNCTION__)); | |||
1070 | auto &DependantSymEntry = DependantSymI->second; | |||
1071 | ||||
1072 | // If the dependant is emitted and this node was the last of its | |||
1073 | // unemitted dependencies then the dependant node is now ready, so | |||
1074 | // notify any pending queries on the dependant node. | |||
1075 | if (DependantSymEntry.getState() == SymbolState::Emitted && | |||
1076 | DependantMI.UnemittedDependencies.empty()) { | |||
1077 | assert(DependantMI.Dependants.empty() &&(static_cast <bool> (DependantMI.Dependants.empty() && "Dependants should be empty by now") ? void (0) : __assert_fail ("DependantMI.Dependants.empty() && \"Dependants should be empty by now\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1078, __extension__ __PRETTY_FUNCTION__)) | |||
1078 | "Dependants should be empty by now")(static_cast <bool> (DependantMI.Dependants.empty() && "Dependants should be empty by now") ? void (0) : __assert_fail ("DependantMI.Dependants.empty() && \"Dependants should be empty by now\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1078, __extension__ __PRETTY_FUNCTION__)); | |||
1079 | ||||
1080 | // Since this dependant is now ready, we erase its | |||
1081 | // MaterializingInfo and update its materializing state. | |||
1082 | DependantSymEntry.setState(SymbolState::Ready); | |||
1083 | DependantJDReadySymbols.push_back(DependantName); | |||
1084 | ||||
1085 | for (auto &Q : | |||
1086 | DependantMI.takeQueriesMeeting(SymbolState::Ready)) { | |||
1087 | Q->notifySymbolMetRequiredState( | |||
1088 | DependantName, DependantSymI->second.getSymbol()); | |||
1089 | if (Q->isComplete()) | |||
1090 | CompletedQueries.insert(Q); | |||
1091 | Q->removeQueryDependence(DependantJD, DependantName); | |||
1092 | } | |||
1093 | DependantJD.MaterializingInfos.erase(DependantMII); | |||
1094 | } | |||
1095 | } | |||
1096 | } | |||
1097 | ||||
1098 | auto &ThisJDReadySymbols = ReadySymbols[this]; | |||
1099 | MI.Dependants.clear(); | |||
1100 | if (MI.UnemittedDependencies.empty()) { | |||
1101 | SymI->second.setState(SymbolState::Ready); | |||
1102 | ThisJDReadySymbols.push_back(Name); | |||
1103 | for (auto &Q : MI.takeQueriesMeeting(SymbolState::Ready)) { | |||
1104 | Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol()); | |||
1105 | if (Q->isComplete()) | |||
1106 | CompletedQueries.insert(Q); | |||
1107 | Q->removeQueryDependence(*this, Name); | |||
1108 | } | |||
1109 | MaterializingInfos.erase(MII); | |||
1110 | } | |||
1111 | } | |||
1112 | ||||
1113 | return Error::success(); | |||
1114 | })) | |||
1115 | return Err; | |||
1116 | ||||
1117 | // Otherwise notify all the completed queries. | |||
1118 | for (auto &Q : CompletedQueries) { | |||
1119 | assert(Q->isComplete() && "Q is not complete")(static_cast <bool> (Q->isComplete() && "Q is not complete" ) ? void (0) : __assert_fail ("Q->isComplete() && \"Q is not complete\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1119, __extension__ __PRETTY_FUNCTION__)); | |||
1120 | Q->handleComplete(); | |||
1121 | } | |||
1122 | ||||
1123 | return Error::success(); | |||
1124 | } | |||
1125 | ||||
1126 | void JITDylib::unlinkMaterializationResponsibility( | |||
1127 | MaterializationResponsibility &MR) { | |||
1128 | ES.runSessionLocked([&]() { | |||
1129 | auto I = MRTrackers.find(&MR); | |||
1130 | assert(I != MRTrackers.end() && "MaterializationResponsibility not linked")(static_cast <bool> (I != MRTrackers.end() && "MaterializationResponsibility not linked" ) ? void (0) : __assert_fail ("I != MRTrackers.end() && \"MaterializationResponsibility not linked\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1130, __extension__ __PRETTY_FUNCTION__)); | |||
1131 | MRTrackers.erase(I); | |||
1132 | }); | |||
1133 | } | |||
1134 | ||||
1135 | std::pair<JITDylib::AsynchronousSymbolQuerySet, | |||
1136 | std::shared_ptr<SymbolDependenceMap>> | |||
1137 | JITDylib::failSymbols(FailedSymbolsWorklist Worklist) { | |||
1138 | AsynchronousSymbolQuerySet FailedQueries; | |||
1139 | auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>(); | |||
1140 | ||||
1141 | while (!Worklist.empty()) { | |||
1142 | assert(Worklist.back().first && "Failed JITDylib can not be null")(static_cast <bool> (Worklist.back().first && "Failed JITDylib can not be null" ) ? void (0) : __assert_fail ("Worklist.back().first && \"Failed JITDylib can not be null\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1142, __extension__ __PRETTY_FUNCTION__)); | |||
1143 | auto &JD = *Worklist.back().first; | |||
1144 | auto Name = std::move(Worklist.back().second); | |||
1145 | Worklist.pop_back(); | |||
1146 | ||||
1147 | (*FailedSymbolsMap)[&JD].insert(Name); | |||
1148 | ||||
1149 | assert(JD.Symbols.count(Name) && "No symbol table entry for Name")(static_cast <bool> (JD.Symbols.count(Name) && "No symbol table entry for Name" ) ? void (0) : __assert_fail ("JD.Symbols.count(Name) && \"No symbol table entry for Name\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1149, __extension__ __PRETTY_FUNCTION__)); | |||
1150 | auto &Sym = JD.Symbols[Name]; | |||
1151 | ||||
1152 | // Move the symbol into the error state. | |||
1153 | // Note that this may be redundant: The symbol might already have been | |||
1154 | // moved to this state in response to the failure of a dependence. | |||
1155 | Sym.setFlags(Sym.getFlags() | JITSymbolFlags::HasError); | |||
1156 | ||||
1157 | // FIXME: Come up with a sane mapping of state to | |||
1158 | // presence-of-MaterializingInfo so that we can assert presence / absence | |||
1159 | // here, rather than testing it. | |||
1160 | auto MII = JD.MaterializingInfos.find(Name); | |||
1161 | ||||
1162 | if (MII == JD.MaterializingInfos.end()) | |||
1163 | continue; | |||
1164 | ||||
1165 | auto &MI = MII->second; | |||
1166 | ||||
1167 | // Move all dependants to the error state and disconnect from them. | |||
1168 | for (auto &KV : MI.Dependants) { | |||
1169 | auto &DependantJD = *KV.first; | |||
1170 | for (auto &DependantName : KV.second) { | |||
1171 | assert(DependantJD.Symbols.count(DependantName) &&(static_cast <bool> (DependantJD.Symbols.count(DependantName ) && "No symbol table entry for DependantName") ? void (0) : __assert_fail ("DependantJD.Symbols.count(DependantName) && \"No symbol table entry for DependantName\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1172, __extension__ __PRETTY_FUNCTION__)) | |||
1172 | "No symbol table entry for DependantName")(static_cast <bool> (DependantJD.Symbols.count(DependantName ) && "No symbol table entry for DependantName") ? void (0) : __assert_fail ("DependantJD.Symbols.count(DependantName) && \"No symbol table entry for DependantName\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1172, __extension__ __PRETTY_FUNCTION__)); | |||
1173 | auto &DependantSym = DependantJD.Symbols[DependantName]; | |||
1174 | DependantSym.setFlags(DependantSym.getFlags() | | |||
1175 | JITSymbolFlags::HasError); | |||
1176 | ||||
1177 | assert(DependantJD.MaterializingInfos.count(DependantName) &&(static_cast <bool> (DependantJD.MaterializingInfos.count (DependantName) && "No MaterializingInfo for dependant" ) ? void (0) : __assert_fail ("DependantJD.MaterializingInfos.count(DependantName) && \"No MaterializingInfo for dependant\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1178, __extension__ __PRETTY_FUNCTION__)) | |||
1178 | "No MaterializingInfo for dependant")(static_cast <bool> (DependantJD.MaterializingInfos.count (DependantName) && "No MaterializingInfo for dependant" ) ? void (0) : __assert_fail ("DependantJD.MaterializingInfos.count(DependantName) && \"No MaterializingInfo for dependant\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1178, __extension__ __PRETTY_FUNCTION__)); | |||
1179 | auto &DependantMI = DependantJD.MaterializingInfos[DependantName]; | |||
1180 | ||||
1181 | auto UnemittedDepI = DependantMI.UnemittedDependencies.find(&JD); | |||
1182 | assert(UnemittedDepI != DependantMI.UnemittedDependencies.end() &&(static_cast <bool> (UnemittedDepI != DependantMI.UnemittedDependencies .end() && "No UnemittedDependencies entry for this JITDylib" ) ? void (0) : __assert_fail ("UnemittedDepI != DependantMI.UnemittedDependencies.end() && \"No UnemittedDependencies entry for this JITDylib\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1183, __extension__ __PRETTY_FUNCTION__)) | |||
1183 | "No UnemittedDependencies entry for this JITDylib")(static_cast <bool> (UnemittedDepI != DependantMI.UnemittedDependencies .end() && "No UnemittedDependencies entry for this JITDylib" ) ? void (0) : __assert_fail ("UnemittedDepI != DependantMI.UnemittedDependencies.end() && \"No UnemittedDependencies entry for this JITDylib\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1183, __extension__ __PRETTY_FUNCTION__)); | |||
1184 | assert(UnemittedDepI->second.count(Name) &&(static_cast <bool> (UnemittedDepI->second.count(Name ) && "No UnemittedDependencies entry for this symbol" ) ? void (0) : __assert_fail ("UnemittedDepI->second.count(Name) && \"No UnemittedDependencies entry for this symbol\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1185, __extension__ __PRETTY_FUNCTION__)) | |||
1185 | "No UnemittedDependencies entry for this symbol")(static_cast <bool> (UnemittedDepI->second.count(Name ) && "No UnemittedDependencies entry for this symbol" ) ? void (0) : __assert_fail ("UnemittedDepI->second.count(Name) && \"No UnemittedDependencies entry for this symbol\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1185, __extension__ __PRETTY_FUNCTION__)); | |||
1186 | UnemittedDepI->second.erase(Name); | |||
1187 | if (UnemittedDepI->second.empty()) | |||
1188 | DependantMI.UnemittedDependencies.erase(UnemittedDepI); | |||
1189 | ||||
1190 | // If this symbol is already in the emitted state then we need to | |||
1191 | // take responsibility for failing its queries, so add it to the | |||
1192 | // worklist. | |||
1193 | if (DependantSym.getState() == SymbolState::Emitted) { | |||
1194 | assert(DependantMI.Dependants.empty() &&(static_cast <bool> (DependantMI.Dependants.empty() && "Emitted symbol should not have dependants") ? void (0) : __assert_fail ("DependantMI.Dependants.empty() && \"Emitted symbol should not have dependants\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1195, __extension__ __PRETTY_FUNCTION__)) | |||
1195 | "Emitted symbol should not have dependants")(static_cast <bool> (DependantMI.Dependants.empty() && "Emitted symbol should not have dependants") ? void (0) : __assert_fail ("DependantMI.Dependants.empty() && \"Emitted symbol should not have dependants\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1195, __extension__ __PRETTY_FUNCTION__)); | |||
1196 | Worklist.push_back(std::make_pair(&DependantJD, DependantName)); | |||
1197 | } | |||
1198 | } | |||
1199 | } | |||
1200 | MI.Dependants.clear(); | |||
1201 | ||||
1202 | // Disconnect from all unemitted depenencies. | |||
1203 | for (auto &KV : MI.UnemittedDependencies) { | |||
1204 | auto &UnemittedDepJD = *KV.first; | |||
1205 | for (auto &UnemittedDepName : KV.second) { | |||
1206 | auto UnemittedDepMII = | |||
1207 | UnemittedDepJD.MaterializingInfos.find(UnemittedDepName); | |||
1208 | assert(UnemittedDepMII != UnemittedDepJD.MaterializingInfos.end() &&(static_cast <bool> (UnemittedDepMII != UnemittedDepJD. MaterializingInfos.end() && "Missing MII for unemitted dependency" ) ? void (0) : __assert_fail ("UnemittedDepMII != UnemittedDepJD.MaterializingInfos.end() && \"Missing MII for unemitted dependency\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1209, __extension__ __PRETTY_FUNCTION__)) | |||
1209 | "Missing MII for unemitted dependency")(static_cast <bool> (UnemittedDepMII != UnemittedDepJD. MaterializingInfos.end() && "Missing MII for unemitted dependency" ) ? void (0) : __assert_fail ("UnemittedDepMII != UnemittedDepJD.MaterializingInfos.end() && \"Missing MII for unemitted dependency\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1209, __extension__ __PRETTY_FUNCTION__)); | |||
1210 | assert(UnemittedDepMII->second.Dependants.count(&JD) &&(static_cast <bool> (UnemittedDepMII->second.Dependants .count(&JD) && "JD not listed as a dependant of unemitted dependency" ) ? void (0) : __assert_fail ("UnemittedDepMII->second.Dependants.count(&JD) && \"JD not listed as a dependant of unemitted dependency\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1211, __extension__ __PRETTY_FUNCTION__)) | |||
1211 | "JD not listed as a dependant of unemitted dependency")(static_cast <bool> (UnemittedDepMII->second.Dependants .count(&JD) && "JD not listed as a dependant of unemitted dependency" ) ? void (0) : __assert_fail ("UnemittedDepMII->second.Dependants.count(&JD) && \"JD not listed as a dependant of unemitted dependency\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1211, __extension__ __PRETTY_FUNCTION__)); | |||
1212 | assert(UnemittedDepMII->second.Dependants[&JD].count(Name) &&(static_cast <bool> (UnemittedDepMII->second.Dependants [&JD].count(Name) && "Name is not listed as a dependant of unemitted dependency" ) ? void (0) : __assert_fail ("UnemittedDepMII->second.Dependants[&JD].count(Name) && \"Name is not listed as a dependant of unemitted dependency\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1213, __extension__ __PRETTY_FUNCTION__)) | |||
1213 | "Name is not listed as a dependant of unemitted dependency")(static_cast <bool> (UnemittedDepMII->second.Dependants [&JD].count(Name) && "Name is not listed as a dependant of unemitted dependency" ) ? void (0) : __assert_fail ("UnemittedDepMII->second.Dependants[&JD].count(Name) && \"Name is not listed as a dependant of unemitted dependency\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1213, __extension__ __PRETTY_FUNCTION__)); | |||
1214 | UnemittedDepMII->second.Dependants[&JD].erase(Name); | |||
1215 | if (UnemittedDepMII->second.Dependants[&JD].empty()) | |||
1216 | UnemittedDepMII->second.Dependants.erase(&JD); | |||
1217 | } | |||
1218 | } | |||
1219 | MI.UnemittedDependencies.clear(); | |||
1220 | ||||
1221 | // Collect queries to be failed for this MII. | |||
1222 | AsynchronousSymbolQueryList ToDetach; | |||
1223 | for (auto &Q : MII->second.pendingQueries()) { | |||
1224 | // Add the query to the list to be failed and detach it. | |||
1225 | FailedQueries.insert(Q); | |||
1226 | ToDetach.push_back(Q); | |||
1227 | } | |||
1228 | for (auto &Q : ToDetach) | |||
1229 | Q->detach(); | |||
1230 | ||||
1231 | assert(MI.Dependants.empty() &&(static_cast <bool> (MI.Dependants.empty() && "Can not delete MaterializingInfo with dependants still attached" ) ? void (0) : __assert_fail ("MI.Dependants.empty() && \"Can not delete MaterializingInfo with dependants still attached\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1232, __extension__ __PRETTY_FUNCTION__)) | |||
1232 | "Can not delete MaterializingInfo with dependants still attached")(static_cast <bool> (MI.Dependants.empty() && "Can not delete MaterializingInfo with dependants still attached" ) ? void (0) : __assert_fail ("MI.Dependants.empty() && \"Can not delete MaterializingInfo with dependants still attached\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1232, __extension__ __PRETTY_FUNCTION__)); | |||
1233 | assert(MI.UnemittedDependencies.empty() &&(static_cast <bool> (MI.UnemittedDependencies.empty() && "Can not delete MaterializingInfo with unemitted dependencies " "still attached") ? void (0) : __assert_fail ("MI.UnemittedDependencies.empty() && \"Can not delete MaterializingInfo with unemitted dependencies \" \"still attached\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1235, __extension__ __PRETTY_FUNCTION__)) | |||
1234 | "Can not delete MaterializingInfo with unemitted dependencies "(static_cast <bool> (MI.UnemittedDependencies.empty() && "Can not delete MaterializingInfo with unemitted dependencies " "still attached") ? void (0) : __assert_fail ("MI.UnemittedDependencies.empty() && \"Can not delete MaterializingInfo with unemitted dependencies \" \"still attached\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1235, __extension__ __PRETTY_FUNCTION__)) | |||
1235 | "still attached")(static_cast <bool> (MI.UnemittedDependencies.empty() && "Can not delete MaterializingInfo with unemitted dependencies " "still attached") ? void (0) : __assert_fail ("MI.UnemittedDependencies.empty() && \"Can not delete MaterializingInfo with unemitted dependencies \" \"still attached\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1235, __extension__ __PRETTY_FUNCTION__)); | |||
1236 | assert(!MI.hasQueriesPending() &&(static_cast <bool> (!MI.hasQueriesPending() && "Can not delete MaterializingInfo with queries pending") ? void (0) : __assert_fail ("!MI.hasQueriesPending() && \"Can not delete MaterializingInfo with queries pending\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1237, __extension__ __PRETTY_FUNCTION__)) | |||
1237 | "Can not delete MaterializingInfo with queries pending")(static_cast <bool> (!MI.hasQueriesPending() && "Can not delete MaterializingInfo with queries pending") ? void (0) : __assert_fail ("!MI.hasQueriesPending() && \"Can not delete MaterializingInfo with queries pending\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1237, __extension__ __PRETTY_FUNCTION__)); | |||
1238 | JD.MaterializingInfos.erase(MII); | |||
1239 | } | |||
1240 | ||||
1241 | return std::make_pair(std::move(FailedQueries), std::move(FailedSymbolsMap)); | |||
1242 | } | |||
1243 | ||||
1244 | void JITDylib::setLinkOrder(JITDylibSearchOrder NewLinkOrder, | |||
1245 | bool LinkAgainstThisJITDylibFirst) { | |||
1246 | ES.runSessionLocked([&]() { | |||
1247 | if (LinkAgainstThisJITDylibFirst) { | |||
1248 | LinkOrder.clear(); | |||
1249 | if (NewLinkOrder.empty() || NewLinkOrder.front().first != this) | |||
1250 | LinkOrder.push_back( | |||
1251 | std::make_pair(this, JITDylibLookupFlags::MatchAllSymbols)); | |||
1252 | llvm::append_range(LinkOrder, NewLinkOrder); | |||
1253 | } else | |||
1254 | LinkOrder = std::move(NewLinkOrder); | |||
1255 | }); | |||
1256 | } | |||
1257 | ||||
1258 | void JITDylib::addToLinkOrder(JITDylib &JD, JITDylibLookupFlags JDLookupFlags) { | |||
1259 | ES.runSessionLocked([&]() { LinkOrder.push_back({&JD, JDLookupFlags}); }); | |||
1260 | } | |||
1261 | ||||
1262 | void JITDylib::replaceInLinkOrder(JITDylib &OldJD, JITDylib &NewJD, | |||
1263 | JITDylibLookupFlags JDLookupFlags) { | |||
1264 | ES.runSessionLocked([&]() { | |||
1265 | for (auto &KV : LinkOrder) | |||
1266 | if (KV.first == &OldJD) { | |||
1267 | KV = {&NewJD, JDLookupFlags}; | |||
1268 | break; | |||
1269 | } | |||
1270 | }); | |||
1271 | } | |||
1272 | ||||
1273 | void JITDylib::removeFromLinkOrder(JITDylib &JD) { | |||
1274 | ES.runSessionLocked([&]() { | |||
1275 | auto I = llvm::find_if(LinkOrder, | |||
1276 | [&](const JITDylibSearchOrder::value_type &KV) { | |||
1277 | return KV.first == &JD; | |||
1278 | }); | |||
1279 | if (I != LinkOrder.end()) | |||
1280 | LinkOrder.erase(I); | |||
1281 | }); | |||
1282 | } | |||
1283 | ||||
1284 | Error JITDylib::remove(const SymbolNameSet &Names) { | |||
1285 | return ES.runSessionLocked([&]() -> Error { | |||
1286 | using SymbolMaterializerItrPair = | |||
1287 | std::pair<SymbolTable::iterator, UnmaterializedInfosMap::iterator>; | |||
1288 | std::vector<SymbolMaterializerItrPair> SymbolsToRemove; | |||
1289 | SymbolNameSet Missing; | |||
1290 | SymbolNameSet Materializing; | |||
1291 | ||||
1292 | for (auto &Name : Names) { | |||
1293 | auto I = Symbols.find(Name); | |||
1294 | ||||
1295 | // Note symbol missing. | |||
1296 | if (I == Symbols.end()) { | |||
1297 | Missing.insert(Name); | |||
1298 | continue; | |||
1299 | } | |||
1300 | ||||
1301 | // Note symbol materializing. | |||
1302 | if (I->second.getState() != SymbolState::NeverSearched && | |||
1303 | I->second.getState() != SymbolState::Ready) { | |||
1304 | Materializing.insert(Name); | |||
1305 | continue; | |||
1306 | } | |||
1307 | ||||
1308 | auto UMII = I->second.hasMaterializerAttached() | |||
1309 | ? UnmaterializedInfos.find(Name) | |||
1310 | : UnmaterializedInfos.end(); | |||
1311 | SymbolsToRemove.push_back(std::make_pair(I, UMII)); | |||
1312 | } | |||
1313 | ||||
1314 | // If any of the symbols are not defined, return an error. | |||
1315 | if (!Missing.empty()) | |||
1316 | return make_error<SymbolsNotFound>(std::move(Missing)); | |||
1317 | ||||
1318 | // If any of the symbols are currently materializing, return an error. | |||
1319 | if (!Materializing.empty()) | |||
1320 | return make_error<SymbolsCouldNotBeRemoved>(std::move(Materializing)); | |||
1321 | ||||
1322 | // Remove the symbols. | |||
1323 | for (auto &SymbolMaterializerItrPair : SymbolsToRemove) { | |||
1324 | auto UMII = SymbolMaterializerItrPair.second; | |||
1325 | ||||
1326 | // If there is a materializer attached, call discard. | |||
1327 | if (UMII != UnmaterializedInfos.end()) { | |||
1328 | UMII->second->MU->doDiscard(*this, UMII->first); | |||
1329 | UnmaterializedInfos.erase(UMII); | |||
1330 | } | |||
1331 | ||||
1332 | auto SymI = SymbolMaterializerItrPair.first; | |||
1333 | Symbols.erase(SymI); | |||
1334 | } | |||
1335 | ||||
1336 | return Error::success(); | |||
1337 | }); | |||
1338 | } | |||
1339 | ||||
1340 | void JITDylib::dump(raw_ostream &OS) { | |||
1341 | ES.runSessionLocked([&, this]() { | |||
1342 | OS << "JITDylib \"" << JITDylibName << "\" (ES: " | |||
1343 | << format("0x%016" PRIx64"l" "x", reinterpret_cast<uintptr_t>(&ES)) << "):\n" | |||
1344 | << "Link order: " << LinkOrder << "\n" | |||
1345 | << "Symbol table:\n"; | |||
1346 | ||||
1347 | for (auto &KV : Symbols) { | |||
1348 | OS << " \"" << *KV.first << "\": "; | |||
1349 | if (auto Addr = KV.second.getAddress()) | |||
1350 | OS << format("0x%016" PRIx64"l" "x", Addr) << ", " << KV.second.getFlags() | |||
1351 | << " "; | |||
1352 | else | |||
1353 | OS << "<not resolved> "; | |||
1354 | ||||
1355 | OS << KV.second.getFlags() << " " << KV.second.getState(); | |||
1356 | ||||
1357 | if (KV.second.hasMaterializerAttached()) { | |||
1358 | OS << " (Materializer "; | |||
1359 | auto I = UnmaterializedInfos.find(KV.first); | |||
1360 | assert(I != UnmaterializedInfos.end() &&(static_cast <bool> (I != UnmaterializedInfos.end() && "Lazy symbol should have UnmaterializedInfo") ? void (0) : __assert_fail ("I != UnmaterializedInfos.end() && \"Lazy symbol should have UnmaterializedInfo\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1361, __extension__ __PRETTY_FUNCTION__)) | |||
1361 | "Lazy symbol should have UnmaterializedInfo")(static_cast <bool> (I != UnmaterializedInfos.end() && "Lazy symbol should have UnmaterializedInfo") ? void (0) : __assert_fail ("I != UnmaterializedInfos.end() && \"Lazy symbol should have UnmaterializedInfo\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1361, __extension__ __PRETTY_FUNCTION__)); | |||
1362 | OS << I->second->MU.get() << ", " << I->second->MU->getName() << ")\n"; | |||
1363 | } else | |||
1364 | OS << "\n"; | |||
1365 | } | |||
1366 | ||||
1367 | if (!MaterializingInfos.empty()) | |||
1368 | OS << " MaterializingInfos entries:\n"; | |||
1369 | for (auto &KV : MaterializingInfos) { | |||
1370 | OS << " \"" << *KV.first << "\":\n" | |||
1371 | << " " << KV.second.pendingQueries().size() | |||
1372 | << " pending queries: { "; | |||
1373 | for (const auto &Q : KV.second.pendingQueries()) | |||
1374 | OS << Q.get() << " (" << Q->getRequiredState() << ") "; | |||
1375 | OS << "}\n Dependants:\n"; | |||
1376 | for (auto &KV2 : KV.second.Dependants) | |||
1377 | OS << " " << KV2.first->getName() << ": " << KV2.second << "\n"; | |||
1378 | OS << " Unemitted Dependencies:\n"; | |||
1379 | for (auto &KV2 : KV.second.UnemittedDependencies) | |||
1380 | OS << " " << KV2.first->getName() << ": " << KV2.second << "\n"; | |||
1381 | assert((Symbols[KV.first].getState() != SymbolState::Ready ||(static_cast <bool> ((Symbols[KV.first].getState() != SymbolState ::Ready || !KV.second.pendingQueries().empty() || !KV.second. Dependants.empty() || !KV.second.UnemittedDependencies.empty( )) && "Stale materializing info entry") ? void (0) : __assert_fail ("(Symbols[KV.first].getState() != SymbolState::Ready || !KV.second.pendingQueries().empty() || !KV.second.Dependants.empty() || !KV.second.UnemittedDependencies.empty()) && \"Stale materializing info entry\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1385, __extension__ __PRETTY_FUNCTION__)) | |||
1382 | !KV.second.pendingQueries().empty() ||(static_cast <bool> ((Symbols[KV.first].getState() != SymbolState ::Ready || !KV.second.pendingQueries().empty() || !KV.second. Dependants.empty() || !KV.second.UnemittedDependencies.empty( )) && "Stale materializing info entry") ? void (0) : __assert_fail ("(Symbols[KV.first].getState() != SymbolState::Ready || !KV.second.pendingQueries().empty() || !KV.second.Dependants.empty() || !KV.second.UnemittedDependencies.empty()) && \"Stale materializing info entry\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1385, __extension__ __PRETTY_FUNCTION__)) | |||
1383 | !KV.second.Dependants.empty() ||(static_cast <bool> ((Symbols[KV.first].getState() != SymbolState ::Ready || !KV.second.pendingQueries().empty() || !KV.second. Dependants.empty() || !KV.second.UnemittedDependencies.empty( )) && "Stale materializing info entry") ? void (0) : __assert_fail ("(Symbols[KV.first].getState() != SymbolState::Ready || !KV.second.pendingQueries().empty() || !KV.second.Dependants.empty() || !KV.second.UnemittedDependencies.empty()) && \"Stale materializing info entry\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1385, __extension__ __PRETTY_FUNCTION__)) | |||
1384 | !KV.second.UnemittedDependencies.empty()) &&(static_cast <bool> ((Symbols[KV.first].getState() != SymbolState ::Ready || !KV.second.pendingQueries().empty() || !KV.second. Dependants.empty() || !KV.second.UnemittedDependencies.empty( )) && "Stale materializing info entry") ? void (0) : __assert_fail ("(Symbols[KV.first].getState() != SymbolState::Ready || !KV.second.pendingQueries().empty() || !KV.second.Dependants.empty() || !KV.second.UnemittedDependencies.empty()) && \"Stale materializing info entry\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1385, __extension__ __PRETTY_FUNCTION__)) | |||
1385 | "Stale materializing info entry")(static_cast <bool> ((Symbols[KV.first].getState() != SymbolState ::Ready || !KV.second.pendingQueries().empty() || !KV.second. Dependants.empty() || !KV.second.UnemittedDependencies.empty( )) && "Stale materializing info entry") ? void (0) : __assert_fail ("(Symbols[KV.first].getState() != SymbolState::Ready || !KV.second.pendingQueries().empty() || !KV.second.Dependants.empty() || !KV.second.UnemittedDependencies.empty()) && \"Stale materializing info entry\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1385, __extension__ __PRETTY_FUNCTION__)); | |||
1386 | } | |||
1387 | }); | |||
1388 | } | |||
1389 | ||||
1390 | void JITDylib::MaterializingInfo::addQuery( | |||
1391 | std::shared_ptr<AsynchronousSymbolQuery> Q) { | |||
1392 | ||||
1393 | auto I = std::lower_bound( | |||
1394 | PendingQueries.rbegin(), PendingQueries.rend(), Q->getRequiredState(), | |||
1395 | [](const std::shared_ptr<AsynchronousSymbolQuery> &V, SymbolState S) { | |||
1396 | return V->getRequiredState() <= S; | |||
1397 | }); | |||
1398 | PendingQueries.insert(I.base(), std::move(Q)); | |||
1399 | } | |||
1400 | ||||
1401 | void JITDylib::MaterializingInfo::removeQuery( | |||
1402 | const AsynchronousSymbolQuery &Q) { | |||
1403 | // FIXME: Implement 'find_as' for shared_ptr<T>/T*. | |||
1404 | auto I = llvm::find_if( | |||
1405 | PendingQueries, [&Q](const std::shared_ptr<AsynchronousSymbolQuery> &V) { | |||
1406 | return V.get() == &Q; | |||
1407 | }); | |||
1408 | assert(I != PendingQueries.end() &&(static_cast <bool> (I != PendingQueries.end() && "Query is not attached to this MaterializingInfo") ? void (0 ) : __assert_fail ("I != PendingQueries.end() && \"Query is not attached to this MaterializingInfo\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1409, __extension__ __PRETTY_FUNCTION__)) | |||
1409 | "Query is not attached to this MaterializingInfo")(static_cast <bool> (I != PendingQueries.end() && "Query is not attached to this MaterializingInfo") ? void (0 ) : __assert_fail ("I != PendingQueries.end() && \"Query is not attached to this MaterializingInfo\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1409, __extension__ __PRETTY_FUNCTION__)); | |||
1410 | PendingQueries.erase(I); | |||
1411 | } | |||
1412 | ||||
1413 | JITDylib::AsynchronousSymbolQueryList | |||
1414 | JITDylib::MaterializingInfo::takeQueriesMeeting(SymbolState RequiredState) { | |||
1415 | AsynchronousSymbolQueryList Result; | |||
1416 | while (!PendingQueries.empty()) { | |||
1417 | if (PendingQueries.back()->getRequiredState() > RequiredState) | |||
1418 | break; | |||
1419 | ||||
1420 | Result.push_back(std::move(PendingQueries.back())); | |||
1421 | PendingQueries.pop_back(); | |||
1422 | } | |||
1423 | ||||
1424 | return Result; | |||
1425 | } | |||
1426 | ||||
1427 | JITDylib::JITDylib(ExecutionSession &ES, std::string Name) | |||
1428 | : ES(ES), JITDylibName(std::move(Name)) { | |||
1429 | LinkOrder.push_back({this, JITDylibLookupFlags::MatchAllSymbols}); | |||
1430 | } | |||
1431 | ||||
1432 | ResourceTrackerSP JITDylib::getTracker(MaterializationResponsibility &MR) { | |||
1433 | auto I = MRTrackers.find(&MR); | |||
1434 | assert(I != MRTrackers.end() && "MR is not linked")(static_cast <bool> (I != MRTrackers.end() && "MR is not linked" ) ? void (0) : __assert_fail ("I != MRTrackers.end() && \"MR is not linked\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1434, __extension__ __PRETTY_FUNCTION__)); | |||
1435 | assert(I->second && "Linked tracker is null")(static_cast <bool> (I->second && "Linked tracker is null" ) ? void (0) : __assert_fail ("I->second && \"Linked tracker is null\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1435, __extension__ __PRETTY_FUNCTION__)); | |||
1436 | return I->second; | |||
1437 | } | |||
1438 | ||||
1439 | std::pair<JITDylib::AsynchronousSymbolQuerySet, | |||
1440 | std::shared_ptr<SymbolDependenceMap>> | |||
1441 | JITDylib::removeTracker(ResourceTracker &RT) { | |||
1442 | // Note: Should be called under the session lock. | |||
1443 | ||||
1444 | SymbolNameVector SymbolsToRemove; | |||
1445 | std::vector<std::pair<JITDylib *, SymbolStringPtr>> SymbolsToFail; | |||
1446 | ||||
1447 | if (&RT == DefaultTracker.get()) { | |||
1448 | SymbolNameSet TrackedSymbols; | |||
1449 | for (auto &KV : TrackerSymbols) | |||
1450 | for (auto &Sym : KV.second) | |||
1451 | TrackedSymbols.insert(Sym); | |||
1452 | ||||
1453 | for (auto &KV : Symbols) { | |||
1454 | auto &Sym = KV.first; | |||
1455 | if (!TrackedSymbols.count(Sym)) | |||
1456 | SymbolsToRemove.push_back(Sym); | |||
1457 | } | |||
1458 | ||||
1459 | DefaultTracker.reset(); | |||
1460 | } else { | |||
1461 | /// Check for a non-default tracker. | |||
1462 | auto I = TrackerSymbols.find(&RT); | |||
1463 | if (I != TrackerSymbols.end()) { | |||
1464 | SymbolsToRemove = std::move(I->second); | |||
1465 | TrackerSymbols.erase(I); | |||
1466 | } | |||
1467 | // ... if not found this tracker was already defunct. Nothing to do. | |||
1468 | } | |||
1469 | ||||
1470 | for (auto &Sym : SymbolsToRemove) { | |||
1471 | assert(Symbols.count(Sym) && "Symbol not in symbol table")(static_cast <bool> (Symbols.count(Sym) && "Symbol not in symbol table" ) ? void (0) : __assert_fail ("Symbols.count(Sym) && \"Symbol not in symbol table\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1471, __extension__ __PRETTY_FUNCTION__)); | |||
1472 | ||||
1473 | // If there is a MaterializingInfo then collect any queries to fail. | |||
1474 | auto MII = MaterializingInfos.find(Sym); | |||
1475 | if (MII != MaterializingInfos.end()) | |||
1476 | SymbolsToFail.push_back({this, Sym}); | |||
1477 | } | |||
1478 | ||||
1479 | AsynchronousSymbolQuerySet QueriesToFail; | |||
1480 | auto Result = failSymbols(std::move(SymbolsToFail)); | |||
1481 | ||||
1482 | // Removed symbols should be taken out of the table altogether. | |||
1483 | for (auto &Sym : SymbolsToRemove) { | |||
1484 | auto I = Symbols.find(Sym); | |||
1485 | assert(I != Symbols.end() && "Symbol not present in table")(static_cast <bool> (I != Symbols.end() && "Symbol not present in table" ) ? void (0) : __assert_fail ("I != Symbols.end() && \"Symbol not present in table\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1485, __extension__ __PRETTY_FUNCTION__)); | |||
1486 | ||||
1487 | // Remove Materializer if present. | |||
1488 | if (I->second.hasMaterializerAttached()) { | |||
1489 | // FIXME: Should this discard the symbols? | |||
1490 | UnmaterializedInfos.erase(Sym); | |||
1491 | } else { | |||
1492 | assert(!UnmaterializedInfos.count(Sym) &&(static_cast <bool> (!UnmaterializedInfos.count(Sym) && "Symbol has materializer attached") ? void (0) : __assert_fail ("!UnmaterializedInfos.count(Sym) && \"Symbol has materializer attached\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1493, __extension__ __PRETTY_FUNCTION__)) | |||
1493 | "Symbol has materializer attached")(static_cast <bool> (!UnmaterializedInfos.count(Sym) && "Symbol has materializer attached") ? void (0) : __assert_fail ("!UnmaterializedInfos.count(Sym) && \"Symbol has materializer attached\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1493, __extension__ __PRETTY_FUNCTION__)); | |||
1494 | } | |||
1495 | ||||
1496 | Symbols.erase(I); | |||
1497 | } | |||
1498 | ||||
1499 | return Result; | |||
1500 | } | |||
1501 | ||||
1502 | void JITDylib::transferTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT) { | |||
1503 | assert(&DstRT != &SrcRT && "No-op transfers shouldn't call transferTracker")(static_cast <bool> (&DstRT != &SrcRT && "No-op transfers shouldn't call transferTracker") ? void (0) : __assert_fail ("&DstRT != &SrcRT && \"No-op transfers shouldn't call transferTracker\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1503, __extension__ __PRETTY_FUNCTION__)); | |||
1504 | assert(&DstRT.getJITDylib() == this && "DstRT is not for this JITDylib")(static_cast <bool> (&DstRT.getJITDylib() == this && "DstRT is not for this JITDylib") ? void (0) : __assert_fail ("&DstRT.getJITDylib() == this && \"DstRT is not for this JITDylib\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1504, __extension__ __PRETTY_FUNCTION__)); | |||
1505 | assert(&SrcRT.getJITDylib() == this && "SrcRT is not for this JITDylib")(static_cast <bool> (&SrcRT.getJITDylib() == this && "SrcRT is not for this JITDylib") ? void (0) : __assert_fail ("&SrcRT.getJITDylib() == this && \"SrcRT is not for this JITDylib\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1505, __extension__ __PRETTY_FUNCTION__)); | |||
1506 | ||||
1507 | // Update trackers for any not-yet materialized units. | |||
1508 | for (auto &KV : UnmaterializedInfos) { | |||
1509 | if (KV.second->RT == &SrcRT) | |||
1510 | KV.second->RT = &DstRT; | |||
1511 | } | |||
1512 | ||||
1513 | // Update trackers for any active materialization responsibilities. | |||
1514 | for (auto &KV : MRTrackers) { | |||
1515 | if (KV.second == &SrcRT) | |||
1516 | KV.second = &DstRT; | |||
1517 | } | |||
1518 | ||||
1519 | // If we're transfering to the default tracker we just need to delete the | |||
1520 | // tracked symbols for the source tracker. | |||
1521 | if (&DstRT == DefaultTracker.get()) { | |||
1522 | TrackerSymbols.erase(&SrcRT); | |||
1523 | return; | |||
1524 | } | |||
1525 | ||||
1526 | // If we're transferring from the default tracker we need to find all | |||
1527 | // currently untracked symbols. | |||
1528 | if (&SrcRT == DefaultTracker.get()) { | |||
1529 | assert(!TrackerSymbols.count(&SrcRT) &&(static_cast <bool> (!TrackerSymbols.count(&SrcRT) && "Default tracker should not appear in TrackerSymbols") ? void (0) : __assert_fail ("!TrackerSymbols.count(&SrcRT) && \"Default tracker should not appear in TrackerSymbols\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1530, __extension__ __PRETTY_FUNCTION__)) | |||
1530 | "Default tracker should not appear in TrackerSymbols")(static_cast <bool> (!TrackerSymbols.count(&SrcRT) && "Default tracker should not appear in TrackerSymbols") ? void (0) : __assert_fail ("!TrackerSymbols.count(&SrcRT) && \"Default tracker should not appear in TrackerSymbols\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1530, __extension__ __PRETTY_FUNCTION__)); | |||
1531 | ||||
1532 | SymbolNameVector SymbolsToTrack; | |||
1533 | ||||
1534 | SymbolNameSet CurrentlyTrackedSymbols; | |||
1535 | for (auto &KV : TrackerSymbols) | |||
1536 | for (auto &Sym : KV.second) | |||
1537 | CurrentlyTrackedSymbols.insert(Sym); | |||
1538 | ||||
1539 | for (auto &KV : Symbols) { | |||
1540 | auto &Sym = KV.first; | |||
1541 | if (!CurrentlyTrackedSymbols.count(Sym)) | |||
1542 | SymbolsToTrack.push_back(Sym); | |||
1543 | } | |||
1544 | ||||
1545 | TrackerSymbols[&DstRT] = std::move(SymbolsToTrack); | |||
1546 | return; | |||
1547 | } | |||
1548 | ||||
1549 | auto &DstTrackedSymbols = TrackerSymbols[&DstRT]; | |||
1550 | ||||
1551 | // Finally if neither SrtRT or DstRT are the default tracker then | |||
1552 | // just append DstRT's tracked symbols to SrtRT's. | |||
1553 | auto SI = TrackerSymbols.find(&SrcRT); | |||
1554 | if (SI == TrackerSymbols.end()) | |||
1555 | return; | |||
1556 | ||||
1557 | DstTrackedSymbols.reserve(DstTrackedSymbols.size() + SI->second.size()); | |||
1558 | for (auto &Sym : SI->second) | |||
1559 | DstTrackedSymbols.push_back(std::move(Sym)); | |||
1560 | TrackerSymbols.erase(SI); | |||
1561 | } | |||
1562 | ||||
1563 | Error JITDylib::defineImpl(MaterializationUnit &MU) { | |||
1564 | ||||
1565 | LLVM_DEBUG({ dbgs() << " " << MU.getSymbols() << "\n"; })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " " << MU.getSymbols() << "\n"; }; } } while (false); | |||
1566 | ||||
1567 | SymbolNameSet Duplicates; | |||
1568 | std::vector<SymbolStringPtr> ExistingDefsOverridden; | |||
1569 | std::vector<SymbolStringPtr> MUDefsOverridden; | |||
1570 | ||||
1571 | for (const auto &KV : MU.getSymbols()) { | |||
1572 | auto I = Symbols.find(KV.first); | |||
1573 | ||||
1574 | if (I != Symbols.end()) { | |||
1575 | if (KV.second.isStrong()) { | |||
1576 | if (I->second.getFlags().isStrong() || | |||
1577 | I->second.getState() > SymbolState::NeverSearched) | |||
1578 | Duplicates.insert(KV.first); | |||
1579 | else { | |||
1580 | assert(I->second.getState() == SymbolState::NeverSearched &&(static_cast <bool> (I->second.getState() == SymbolState ::NeverSearched && "Overridden existing def should be in the never-searched " "state") ? void (0) : __assert_fail ("I->second.getState() == SymbolState::NeverSearched && \"Overridden existing def should be in the never-searched \" \"state\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1582, __extension__ __PRETTY_FUNCTION__)) | |||
1581 | "Overridden existing def should be in the never-searched "(static_cast <bool> (I->second.getState() == SymbolState ::NeverSearched && "Overridden existing def should be in the never-searched " "state") ? void (0) : __assert_fail ("I->second.getState() == SymbolState::NeverSearched && \"Overridden existing def should be in the never-searched \" \"state\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1582, __extension__ __PRETTY_FUNCTION__)) | |||
1582 | "state")(static_cast <bool> (I->second.getState() == SymbolState ::NeverSearched && "Overridden existing def should be in the never-searched " "state") ? void (0) : __assert_fail ("I->second.getState() == SymbolState::NeverSearched && \"Overridden existing def should be in the never-searched \" \"state\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1582, __extension__ __PRETTY_FUNCTION__)); | |||
1583 | ExistingDefsOverridden.push_back(KV.first); | |||
1584 | } | |||
1585 | } else | |||
1586 | MUDefsOverridden.push_back(KV.first); | |||
1587 | } | |||
1588 | } | |||
1589 | ||||
1590 | // If there were any duplicate definitions then bail out. | |||
1591 | if (!Duplicates.empty()) { | |||
1592 | LLVM_DEBUG(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " Error: Duplicate symbols " << Duplicates << "\n"; }; } } while (false) | |||
1593 | { dbgs() << " Error: Duplicate symbols " << Duplicates << "\n"; })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " Error: Duplicate symbols " << Duplicates << "\n"; }; } } while (false); | |||
1594 | return make_error<DuplicateDefinition>(std::string(**Duplicates.begin())); | |||
1595 | } | |||
1596 | ||||
1597 | // Discard any overridden defs in this MU. | |||
1598 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { if (!MUDefsOverridden.empty()) dbgs() << " Defs in this MU overridden: " << MUDefsOverridden << "\n"; }; } } while (false ) | |||
1599 | if (!MUDefsOverridden.empty())do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { if (!MUDefsOverridden.empty()) dbgs() << " Defs in this MU overridden: " << MUDefsOverridden << "\n"; }; } } while (false ) | |||
1600 | dbgs() << " Defs in this MU overridden: " << MUDefsOverridden << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { if (!MUDefsOverridden.empty()) dbgs() << " Defs in this MU overridden: " << MUDefsOverridden << "\n"; }; } } while (false ) | |||
1601 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { if (!MUDefsOverridden.empty()) dbgs() << " Defs in this MU overridden: " << MUDefsOverridden << "\n"; }; } } while (false ); | |||
1602 | for (auto &S : MUDefsOverridden) | |||
1603 | MU.doDiscard(*this, S); | |||
1604 | ||||
1605 | // Discard existing overridden defs. | |||
1606 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { if (!ExistingDefsOverridden.empty()) dbgs() << " Existing defs overridden by this MU: " << MUDefsOverridden << "\n"; }; } } while (false) | |||
1607 | if (!ExistingDefsOverridden.empty())do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { if (!ExistingDefsOverridden.empty()) dbgs() << " Existing defs overridden by this MU: " << MUDefsOverridden << "\n"; }; } } while (false) | |||
1608 | dbgs() << " Existing defs overridden by this MU: " << MUDefsOverriddendo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { if (!ExistingDefsOverridden.empty()) dbgs() << " Existing defs overridden by this MU: " << MUDefsOverridden << "\n"; }; } } while (false) | |||
1609 | << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { if (!ExistingDefsOverridden.empty()) dbgs() << " Existing defs overridden by this MU: " << MUDefsOverridden << "\n"; }; } } while (false) | |||
1610 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { if (!ExistingDefsOverridden.empty()) dbgs() << " Existing defs overridden by this MU: " << MUDefsOverridden << "\n"; }; } } while (false); | |||
1611 | for (auto &S : ExistingDefsOverridden) { | |||
1612 | ||||
1613 | auto UMII = UnmaterializedInfos.find(S); | |||
1614 | assert(UMII != UnmaterializedInfos.end() &&(static_cast <bool> (UMII != UnmaterializedInfos.end() && "Overridden existing def should have an UnmaterializedInfo") ? void (0) : __assert_fail ("UMII != UnmaterializedInfos.end() && \"Overridden existing def should have an UnmaterializedInfo\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1615, __extension__ __PRETTY_FUNCTION__)) | |||
1615 | "Overridden existing def should have an UnmaterializedInfo")(static_cast <bool> (UMII != UnmaterializedInfos.end() && "Overridden existing def should have an UnmaterializedInfo") ? void (0) : __assert_fail ("UMII != UnmaterializedInfos.end() && \"Overridden existing def should have an UnmaterializedInfo\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1615, __extension__ __PRETTY_FUNCTION__)); | |||
1616 | UMII->second->MU->doDiscard(*this, S); | |||
1617 | } | |||
1618 | ||||
1619 | // Finally, add the defs from this MU. | |||
1620 | for (auto &KV : MU.getSymbols()) { | |||
1621 | auto &SymEntry = Symbols[KV.first]; | |||
1622 | SymEntry.setFlags(KV.second); | |||
1623 | SymEntry.setState(SymbolState::NeverSearched); | |||
1624 | SymEntry.setMaterializerAttached(true); | |||
1625 | } | |||
1626 | ||||
1627 | return Error::success(); | |||
1628 | } | |||
1629 | ||||
1630 | void JITDylib::installMaterializationUnit( | |||
1631 | std::unique_ptr<MaterializationUnit> MU, ResourceTracker &RT) { | |||
1632 | ||||
1633 | /// defineImpl succeeded. | |||
1634 | if (&RT != DefaultTracker.get()) { | |||
1635 | auto &TS = TrackerSymbols[&RT]; | |||
1636 | TS.reserve(TS.size() + MU->getSymbols().size()); | |||
1637 | for (auto &KV : MU->getSymbols()) | |||
1638 | TS.push_back(KV.first); | |||
1639 | } | |||
1640 | ||||
1641 | auto UMI = std::make_shared<UnmaterializedInfo>(std::move(MU), &RT); | |||
1642 | for (auto &KV : UMI->MU->getSymbols()) | |||
1643 | UnmaterializedInfos[KV.first] = UMI; | |||
1644 | } | |||
1645 | ||||
1646 | void JITDylib::detachQueryHelper(AsynchronousSymbolQuery &Q, | |||
1647 | const SymbolNameSet &QuerySymbols) { | |||
1648 | for (auto &QuerySymbol : QuerySymbols) { | |||
1649 | assert(MaterializingInfos.count(QuerySymbol) &&(static_cast <bool> (MaterializingInfos.count(QuerySymbol ) && "QuerySymbol does not have MaterializingInfo") ? void (0) : __assert_fail ("MaterializingInfos.count(QuerySymbol) && \"QuerySymbol does not have MaterializingInfo\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1650, __extension__ __PRETTY_FUNCTION__)) | |||
1650 | "QuerySymbol does not have MaterializingInfo")(static_cast <bool> (MaterializingInfos.count(QuerySymbol ) && "QuerySymbol does not have MaterializingInfo") ? void (0) : __assert_fail ("MaterializingInfos.count(QuerySymbol) && \"QuerySymbol does not have MaterializingInfo\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1650, __extension__ __PRETTY_FUNCTION__)); | |||
1651 | auto &MI = MaterializingInfos[QuerySymbol]; | |||
1652 | MI.removeQuery(Q); | |||
1653 | } | |||
1654 | } | |||
1655 | ||||
1656 | void JITDylib::transferEmittedNodeDependencies( | |||
1657 | MaterializingInfo &DependantMI, const SymbolStringPtr &DependantName, | |||
1658 | MaterializingInfo &EmittedMI) { | |||
1659 | for (auto &KV : EmittedMI.UnemittedDependencies) { | |||
1660 | auto &DependencyJD = *KV.first; | |||
1661 | SymbolNameSet *UnemittedDependenciesOnDependencyJD = nullptr; | |||
1662 | ||||
1663 | for (auto &DependencyName : KV.second) { | |||
1664 | auto &DependencyMI = DependencyJD.MaterializingInfos[DependencyName]; | |||
1665 | ||||
1666 | // Do not add self dependencies. | |||
1667 | if (&DependencyMI == &DependantMI) | |||
1668 | continue; | |||
1669 | ||||
1670 | // If we haven't looked up the dependencies for DependencyJD yet, do it | |||
1671 | // now and cache the result. | |||
1672 | if (!UnemittedDependenciesOnDependencyJD) | |||
1673 | UnemittedDependenciesOnDependencyJD = | |||
1674 | &DependantMI.UnemittedDependencies[&DependencyJD]; | |||
1675 | ||||
1676 | DependencyMI.Dependants[this].insert(DependantName); | |||
1677 | UnemittedDependenciesOnDependencyJD->insert(DependencyName); | |||
1678 | } | |||
1679 | } | |||
1680 | } | |||
1681 | ||||
1682 | Platform::~Platform() {} | |||
1683 | ||||
1684 | Expected<DenseMap<JITDylib *, SymbolMap>> Platform::lookupInitSymbols( | |||
1685 | ExecutionSession &ES, | |||
1686 | const DenseMap<JITDylib *, SymbolLookupSet> &InitSyms) { | |||
1687 | ||||
1688 | DenseMap<JITDylib *, SymbolMap> CompoundResult; | |||
1689 | Error CompoundErr = Error::success(); | |||
1690 | std::mutex LookupMutex; | |||
1691 | std::condition_variable CV; | |||
1692 | uint64_t Count = InitSyms.size(); | |||
1693 | ||||
1694 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Issuing init-symbol lookup:\n"; for (auto &KV : InitSyms) dbgs() << " " << KV .first->getName() << ": " << KV.second << "\n"; }; } } while (false) | |||
1695 | dbgs() << "Issuing init-symbol lookup:\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Issuing init-symbol lookup:\n"; for (auto &KV : InitSyms) dbgs() << " " << KV .first->getName() << ": " << KV.second << "\n"; }; } } while (false) | |||
1696 | for (auto &KV : InitSyms)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Issuing init-symbol lookup:\n"; for (auto &KV : InitSyms) dbgs() << " " << KV .first->getName() << ": " << KV.second << "\n"; }; } } while (false) | |||
1697 | dbgs() << " " << KV.first->getName() << ": " << KV.second << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Issuing init-symbol lookup:\n"; for (auto &KV : InitSyms) dbgs() << " " << KV .first->getName() << ": " << KV.second << "\n"; }; } } while (false) | |||
1698 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Issuing init-symbol lookup:\n"; for (auto &KV : InitSyms) dbgs() << " " << KV .first->getName() << ": " << KV.second << "\n"; }; } } while (false); | |||
1699 | ||||
1700 | for (auto &KV : InitSyms) { | |||
1701 | auto *JD = KV.first; | |||
1702 | auto Names = std::move(KV.second); | |||
1703 | ES.lookup( | |||
1704 | LookupKind::Static, | |||
1705 | JITDylibSearchOrder({{JD, JITDylibLookupFlags::MatchAllSymbols}}), | |||
1706 | std::move(Names), SymbolState::Ready, | |||
1707 | [&, JD](Expected<SymbolMap> Result) { | |||
1708 | { | |||
1709 | std::lock_guard<std::mutex> Lock(LookupMutex); | |||
1710 | --Count; | |||
1711 | if (Result) { | |||
1712 | assert(!CompoundResult.count(JD) &&(static_cast <bool> (!CompoundResult.count(JD) && "Duplicate JITDylib in lookup?") ? void (0) : __assert_fail ( "!CompoundResult.count(JD) && \"Duplicate JITDylib in lookup?\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1713, __extension__ __PRETTY_FUNCTION__)) | |||
1713 | "Duplicate JITDylib in lookup?")(static_cast <bool> (!CompoundResult.count(JD) && "Duplicate JITDylib in lookup?") ? void (0) : __assert_fail ( "!CompoundResult.count(JD) && \"Duplicate JITDylib in lookup?\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1713, __extension__ __PRETTY_FUNCTION__)); | |||
1714 | CompoundResult[JD] = std::move(*Result); | |||
1715 | } else | |||
1716 | CompoundErr = | |||
1717 | joinErrors(std::move(CompoundErr), Result.takeError()); | |||
1718 | } | |||
1719 | CV.notify_one(); | |||
1720 | }, | |||
1721 | NoDependenciesToRegister); | |||
1722 | } | |||
1723 | ||||
1724 | std::unique_lock<std::mutex> Lock(LookupMutex); | |||
1725 | CV.wait(Lock, [&] { return Count == 0 || CompoundErr; }); | |||
1726 | ||||
1727 | if (CompoundErr) | |||
1728 | return std::move(CompoundErr); | |||
1729 | ||||
1730 | return std::move(CompoundResult); | |||
1731 | } | |||
1732 | ||||
1733 | ExecutionSession::ExecutionSession(std::shared_ptr<SymbolStringPool> SSP) | |||
1734 | : SSP(SSP ? std::move(SSP) : std::make_shared<SymbolStringPool>()) {} | |||
1735 | ||||
1736 | Error ExecutionSession::endSession() { | |||
1737 | LLVM_DEBUG(dbgs() << "Ending ExecutionSession " << this << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "Ending ExecutionSession " << this << "\n"; } } while (false); | |||
1738 | ||||
1739 | std::vector<JITDylibSP> JITDylibsToClose = runSessionLocked([&] { | |||
1740 | SessionOpen = false; | |||
1741 | return std::move(JDs); | |||
1742 | }); | |||
1743 | ||||
1744 | // TODO: notifiy platform? run static deinits? | |||
1745 | ||||
1746 | Error Err = Error::success(); | |||
1747 | for (auto &JD : JITDylibsToClose) | |||
1748 | Err = joinErrors(std::move(Err), JD->clear()); | |||
1749 | return Err; | |||
1750 | } | |||
1751 | ||||
1752 | void ExecutionSession::registerResourceManager(ResourceManager &RM) { | |||
1753 | runSessionLocked([&] { ResourceManagers.push_back(&RM); }); | |||
1754 | } | |||
1755 | ||||
1756 | void ExecutionSession::deregisterResourceManager(ResourceManager &RM) { | |||
1757 | runSessionLocked([&] { | |||
1758 | assert(!ResourceManagers.empty() && "No managers registered")(static_cast <bool> (!ResourceManagers.empty() && "No managers registered") ? void (0) : __assert_fail ("!ResourceManagers.empty() && \"No managers registered\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1758, __extension__ __PRETTY_FUNCTION__)); | |||
1759 | if (ResourceManagers.back() == &RM) | |||
1760 | ResourceManagers.pop_back(); | |||
1761 | else { | |||
1762 | auto I = llvm::find(ResourceManagers, &RM); | |||
1763 | assert(I != ResourceManagers.end() && "RM not registered")(static_cast <bool> (I != ResourceManagers.end() && "RM not registered") ? void (0) : __assert_fail ("I != ResourceManagers.end() && \"RM not registered\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1763, __extension__ __PRETTY_FUNCTION__)); | |||
1764 | ResourceManagers.erase(I); | |||
1765 | } | |||
1766 | }); | |||
1767 | } | |||
1768 | ||||
1769 | JITDylib *ExecutionSession::getJITDylibByName(StringRef Name) { | |||
1770 | return runSessionLocked([&, this]() -> JITDylib * { | |||
1771 | for (auto &JD : JDs) | |||
1772 | if (JD->getName() == Name) | |||
1773 | return JD.get(); | |||
1774 | return nullptr; | |||
1775 | }); | |||
1776 | } | |||
1777 | ||||
1778 | JITDylib &ExecutionSession::createBareJITDylib(std::string Name) { | |||
1779 | assert(!getJITDylibByName(Name) && "JITDylib with that name already exists")(static_cast <bool> (!getJITDylibByName(Name) && "JITDylib with that name already exists") ? void (0) : __assert_fail ("!getJITDylibByName(Name) && \"JITDylib with that name already exists\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1779, __extension__ __PRETTY_FUNCTION__)); | |||
1780 | return runSessionLocked([&, this]() -> JITDylib & { | |||
1781 | JDs.push_back(new JITDylib(*this, std::move(Name))); | |||
1782 | return *JDs.back(); | |||
1783 | }); | |||
1784 | } | |||
1785 | ||||
1786 | Expected<JITDylib &> ExecutionSession::createJITDylib(std::string Name) { | |||
1787 | auto &JD = createBareJITDylib(Name); | |||
1788 | if (P) | |||
1789 | if (auto Err = P->setupJITDylib(JD)) | |||
1790 | return std::move(Err); | |||
1791 | return JD; | |||
1792 | } | |||
1793 | ||||
1794 | std::vector<JITDylibSP> JITDylib::getDFSLinkOrder(ArrayRef<JITDylibSP> JDs) { | |||
1795 | if (JDs.empty()) | |||
1796 | return {}; | |||
1797 | ||||
1798 | auto &ES = JDs.front()->getExecutionSession(); | |||
1799 | return ES.runSessionLocked([&]() { | |||
1800 | DenseSet<JITDylib *> Visited; | |||
1801 | std::vector<JITDylibSP> Result; | |||
1802 | ||||
1803 | for (auto &JD : JDs) { | |||
1804 | ||||
1805 | if (Visited.count(JD.get())) | |||
1806 | continue; | |||
1807 | ||||
1808 | SmallVector<JITDylibSP, 64> WorkStack; | |||
1809 | WorkStack.push_back(JD); | |||
1810 | Visited.insert(JD.get()); | |||
1811 | ||||
1812 | while (!WorkStack.empty()) { | |||
1813 | Result.push_back(std::move(WorkStack.back())); | |||
1814 | WorkStack.pop_back(); | |||
1815 | ||||
1816 | for (auto &KV : llvm::reverse(Result.back()->LinkOrder)) { | |||
1817 | auto &JD = *KV.first; | |||
1818 | if (Visited.count(&JD)) | |||
1819 | continue; | |||
1820 | Visited.insert(&JD); | |||
1821 | WorkStack.push_back(&JD); | |||
1822 | } | |||
1823 | } | |||
1824 | } | |||
1825 | return Result; | |||
1826 | }); | |||
1827 | } | |||
1828 | ||||
1829 | std::vector<JITDylibSP> | |||
1830 | JITDylib::getReverseDFSLinkOrder(ArrayRef<JITDylibSP> JDs) { | |||
1831 | auto Tmp = getDFSLinkOrder(JDs); | |||
1832 | std::reverse(Tmp.begin(), Tmp.end()); | |||
1833 | return Tmp; | |||
1834 | } | |||
1835 | ||||
1836 | std::vector<JITDylibSP> JITDylib::getDFSLinkOrder() { | |||
1837 | return getDFSLinkOrder({this}); | |||
1838 | } | |||
1839 | ||||
1840 | std::vector<JITDylibSP> JITDylib::getReverseDFSLinkOrder() { | |||
1841 | return getReverseDFSLinkOrder({this}); | |||
1842 | } | |||
1843 | ||||
1844 | void ExecutionSession::lookupFlags( | |||
1845 | LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet LookupSet, | |||
1846 | unique_function<void(Expected<SymbolFlagsMap>)> OnComplete) { | |||
1847 | ||||
1848 | OL_applyQueryPhase1(std::make_unique<InProgressLookupFlagsState>( | |||
1849 | K, std::move(SearchOrder), std::move(LookupSet), | |||
1850 | std::move(OnComplete)), | |||
1851 | Error::success()); | |||
1852 | } | |||
1853 | ||||
1854 | Expected<SymbolFlagsMap> | |||
1855 | ExecutionSession::lookupFlags(LookupKind K, JITDylibSearchOrder SearchOrder, | |||
1856 | SymbolLookupSet LookupSet) { | |||
1857 | ||||
1858 | std::promise<MSVCPExpected<SymbolFlagsMap>> ResultP; | |||
1859 | OL_applyQueryPhase1(std::make_unique<InProgressLookupFlagsState>( | |||
1860 | K, std::move(SearchOrder), std::move(LookupSet), | |||
1861 | [&ResultP](Expected<SymbolFlagsMap> Result) { | |||
1862 | ResultP.set_value(std::move(Result)); | |||
1863 | }), | |||
1864 | Error::success()); | |||
1865 | ||||
1866 | auto ResultF = ResultP.get_future(); | |||
1867 | return ResultF.get(); | |||
1868 | } | |||
1869 | ||||
1870 | void ExecutionSession::lookup( | |||
1871 | LookupKind K, const JITDylibSearchOrder &SearchOrder, | |||
1872 | SymbolLookupSet Symbols, SymbolState RequiredState, | |||
1873 | SymbolsResolvedCallback NotifyComplete, | |||
1874 | RegisterDependenciesFunction RegisterDependencies) { | |||
1875 | ||||
1876 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { runSessionLocked([&]() { dbgs() << "Looking up " << Symbols << " in " << SearchOrder << " (required state: " << RequiredState << ")\n"; } ); }; } } while (false) | |||
1877 | runSessionLocked([&]() {do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { runSessionLocked([&]() { dbgs() << "Looking up " << Symbols << " in " << SearchOrder << " (required state: " << RequiredState << ")\n"; } ); }; } } while (false) | |||
1878 | dbgs() << "Looking up " << Symbols << " in " << SearchOrderdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { runSessionLocked([&]() { dbgs() << "Looking up " << Symbols << " in " << SearchOrder << " (required state: " << RequiredState << ")\n"; } ); }; } } while (false) | |||
1879 | << " (required state: " << RequiredState << ")\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { runSessionLocked([&]() { dbgs() << "Looking up " << Symbols << " in " << SearchOrder << " (required state: " << RequiredState << ")\n"; } ); }; } } while (false) | |||
1880 | });do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { runSessionLocked([&]() { dbgs() << "Looking up " << Symbols << " in " << SearchOrder << " (required state: " << RequiredState << ")\n"; } ); }; } } while (false) | |||
1881 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { runSessionLocked([&]() { dbgs() << "Looking up " << Symbols << " in " << SearchOrder << " (required state: " << RequiredState << ")\n"; } ); }; } } while (false); | |||
1882 | ||||
1883 | // lookup can be re-entered recursively if running on a single thread. Run any | |||
1884 | // outstanding MUs in case this query depends on them, otherwise this lookup | |||
1885 | // will starve waiting for a result from an MU that is stuck in the queue. | |||
1886 | dispatchOutstandingMUs(); | |||
1887 | ||||
1888 | auto Unresolved = std::move(Symbols); | |||
1889 | auto Q = std::make_shared<AsynchronousSymbolQuery>(Unresolved, RequiredState, | |||
1890 | std::move(NotifyComplete)); | |||
1891 | ||||
1892 | auto IPLS = std::make_unique<InProgressFullLookupState>( | |||
1893 | K, SearchOrder, std::move(Unresolved), RequiredState, std::move(Q), | |||
1894 | std::move(RegisterDependencies)); | |||
1895 | ||||
1896 | OL_applyQueryPhase1(std::move(IPLS), Error::success()); | |||
1897 | } | |||
1898 | ||||
1899 | Expected<SymbolMap> | |||
1900 | ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder, | |||
1901 | const SymbolLookupSet &Symbols, LookupKind K, | |||
1902 | SymbolState RequiredState, | |||
1903 | RegisterDependenciesFunction RegisterDependencies) { | |||
1904 | #if LLVM_ENABLE_THREADS1 | |||
1905 | // In the threaded case we use promises to return the results. | |||
1906 | std::promise<SymbolMap> PromisedResult; | |||
1907 | Error ResolutionError = Error::success(); | |||
1908 | ||||
1909 | auto NotifyComplete = [&](Expected<SymbolMap> R) { | |||
1910 | if (R) | |||
1911 | PromisedResult.set_value(std::move(*R)); | |||
1912 | else { | |||
1913 | ErrorAsOutParameter _(&ResolutionError); | |||
1914 | ResolutionError = R.takeError(); | |||
1915 | PromisedResult.set_value(SymbolMap()); | |||
1916 | } | |||
1917 | }; | |||
1918 | ||||
1919 | #else | |||
1920 | SymbolMap Result; | |||
1921 | Error ResolutionError = Error::success(); | |||
1922 | ||||
1923 | auto NotifyComplete = [&](Expected<SymbolMap> R) { | |||
1924 | ErrorAsOutParameter _(&ResolutionError); | |||
1925 | if (R) | |||
1926 | Result = std::move(*R); | |||
1927 | else | |||
1928 | ResolutionError = R.takeError(); | |||
1929 | }; | |||
1930 | #endif | |||
1931 | ||||
1932 | // Perform the asynchronous lookup. | |||
1933 | lookup(K, SearchOrder, Symbols, RequiredState, NotifyComplete, | |||
1934 | RegisterDependencies); | |||
1935 | ||||
1936 | #if LLVM_ENABLE_THREADS1 | |||
1937 | auto ResultFuture = PromisedResult.get_future(); | |||
1938 | auto Result = ResultFuture.get(); | |||
1939 | ||||
1940 | if (ResolutionError) | |||
1941 | return std::move(ResolutionError); | |||
1942 | ||||
1943 | return std::move(Result); | |||
1944 | ||||
1945 | #else | |||
1946 | if (ResolutionError) | |||
1947 | return std::move(ResolutionError); | |||
1948 | ||||
1949 | return Result; | |||
1950 | #endif | |||
1951 | } | |||
1952 | ||||
1953 | Expected<JITEvaluatedSymbol> | |||
1954 | ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder, | |||
1955 | SymbolStringPtr Name, SymbolState RequiredState) { | |||
1956 | SymbolLookupSet Names({Name}); | |||
1957 | ||||
1958 | if (auto ResultMap = lookup(SearchOrder, std::move(Names), LookupKind::Static, | |||
1959 | RequiredState, NoDependenciesToRegister)) { | |||
1960 | assert(ResultMap->size() == 1 && "Unexpected number of results")(static_cast <bool> (ResultMap->size() == 1 && "Unexpected number of results") ? void (0) : __assert_fail ( "ResultMap->size() == 1 && \"Unexpected number of results\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1960, __extension__ __PRETTY_FUNCTION__)); | |||
1961 | assert(ResultMap->count(Name) && "Missing result for symbol")(static_cast <bool> (ResultMap->count(Name) && "Missing result for symbol") ? void (0) : __assert_fail ("ResultMap->count(Name) && \"Missing result for symbol\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 1961, __extension__ __PRETTY_FUNCTION__)); | |||
1962 | return std::move(ResultMap->begin()->second); | |||
1963 | } else | |||
1964 | return ResultMap.takeError(); | |||
1965 | } | |||
1966 | ||||
1967 | Expected<JITEvaluatedSymbol> | |||
1968 | ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, SymbolStringPtr Name, | |||
1969 | SymbolState RequiredState) { | |||
1970 | return lookup(makeJITDylibSearchOrder(SearchOrder), Name, RequiredState); | |||
1971 | } | |||
1972 | ||||
1973 | Expected<JITEvaluatedSymbol> | |||
1974 | ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, StringRef Name, | |||
1975 | SymbolState RequiredState) { | |||
1976 | return lookup(SearchOrder, intern(Name), RequiredState); | |||
1977 | } | |||
1978 | ||||
1979 | void ExecutionSession::dump(raw_ostream &OS) { | |||
1980 | runSessionLocked([this, &OS]() { | |||
1981 | for (auto &JD : JDs) | |||
1982 | JD->dump(OS); | |||
1983 | }); | |||
1984 | } | |||
1985 | ||||
1986 | void ExecutionSession::dispatchOutstandingMUs() { | |||
1987 | LLVM_DEBUG(dbgs() << "Dispatching MaterializationUnits...\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "Dispatching MaterializationUnits...\n" ; } } while (false); | |||
1988 | while (1) { | |||
1989 | Optional<std::pair<std::unique_ptr<MaterializationUnit>, | |||
1990 | std::unique_ptr<MaterializationResponsibility>>> | |||
1991 | JMU; | |||
1992 | ||||
1993 | { | |||
1994 | std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex); | |||
1995 | if (!OutstandingMUs.empty()) { | |||
1996 | JMU.emplace(std::move(OutstandingMUs.back())); | |||
1997 | OutstandingMUs.pop_back(); | |||
1998 | } | |||
1999 | } | |||
2000 | ||||
2001 | if (!JMU) | |||
2002 | break; | |||
2003 | ||||
2004 | assert(JMU->first && "No MU?")(static_cast <bool> (JMU->first && "No MU?") ? void (0) : __assert_fail ("JMU->first && \"No MU?\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2004, __extension__ __PRETTY_FUNCTION__)); | |||
2005 | LLVM_DEBUG(dbgs() << " Dispatching \"" << JMU->first->getName() << "\"\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << " Dispatching \"" << JMU-> first->getName() << "\"\n"; } } while (false); | |||
2006 | dispatchMaterialization(std::move(JMU->first), std::move(JMU->second)); | |||
2007 | } | |||
2008 | LLVM_DEBUG(dbgs() << "Done dispatching MaterializationUnits.\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "Done dispatching MaterializationUnits.\n" ; } } while (false); | |||
2009 | } | |||
2010 | ||||
2011 | Error ExecutionSession::removeResourceTracker(ResourceTracker &RT) { | |||
2012 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << RT.getJITDylib(). getName() << " removing tracker " << formatv("{0:x}" , RT.getKeyUnsafe()) << "\n"; }; } } while (false) | |||
2013 | dbgs() << "In " << RT.getJITDylib().getName() << " removing tracker "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << RT.getJITDylib(). getName() << " removing tracker " << formatv("{0:x}" , RT.getKeyUnsafe()) << "\n"; }; } } while (false) | |||
2014 | << formatv("{0:x}", RT.getKeyUnsafe()) << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << RT.getJITDylib(). getName() << " removing tracker " << formatv("{0:x}" , RT.getKeyUnsafe()) << "\n"; }; } } while (false) | |||
2015 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << RT.getJITDylib(). getName() << " removing tracker " << formatv("{0:x}" , RT.getKeyUnsafe()) << "\n"; }; } } while (false); | |||
2016 | std::vector<ResourceManager *> CurrentResourceManagers; | |||
2017 | ||||
2018 | JITDylib::AsynchronousSymbolQuerySet QueriesToFail; | |||
2019 | std::shared_ptr<SymbolDependenceMap> FailedSymbols; | |||
2020 | ||||
2021 | runSessionLocked([&] { | |||
2022 | CurrentResourceManagers = ResourceManagers; | |||
2023 | RT.makeDefunct(); | |||
2024 | std::tie(QueriesToFail, FailedSymbols) = RT.getJITDylib().removeTracker(RT); | |||
2025 | }); | |||
2026 | ||||
2027 | Error Err = Error::success(); | |||
2028 | ||||
2029 | for (auto *L : reverse(CurrentResourceManagers)) | |||
2030 | Err = | |||
2031 | joinErrors(std::move(Err), L->handleRemoveResources(RT.getKeyUnsafe())); | |||
2032 | ||||
2033 | for (auto &Q : QueriesToFail) | |||
2034 | Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbols)); | |||
2035 | ||||
2036 | return Err; | |||
2037 | } | |||
2038 | ||||
2039 | void ExecutionSession::transferResourceTracker(ResourceTracker &DstRT, | |||
2040 | ResourceTracker &SrcRT) { | |||
2041 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << SrcRT.getJITDylib ().getName() << " transfering resources from tracker " << formatv("{0:x}", SrcRT.getKeyUnsafe()) << " to tracker " << formatv("{0:x}", DstRT.getKeyUnsafe()) << "\n" ; }; } } while (false) | |||
2042 | dbgs() << "In " << SrcRT.getJITDylib().getName()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << SrcRT.getJITDylib ().getName() << " transfering resources from tracker " << formatv("{0:x}", SrcRT.getKeyUnsafe()) << " to tracker " << formatv("{0:x}", DstRT.getKeyUnsafe()) << "\n" ; }; } } while (false) | |||
2043 | << " transfering resources from tracker "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << SrcRT.getJITDylib ().getName() << " transfering resources from tracker " << formatv("{0:x}", SrcRT.getKeyUnsafe()) << " to tracker " << formatv("{0:x}", DstRT.getKeyUnsafe()) << "\n" ; }; } } while (false) | |||
2044 | << formatv("{0:x}", SrcRT.getKeyUnsafe()) << " to tracker "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << SrcRT.getJITDylib ().getName() << " transfering resources from tracker " << formatv("{0:x}", SrcRT.getKeyUnsafe()) << " to tracker " << formatv("{0:x}", DstRT.getKeyUnsafe()) << "\n" ; }; } } while (false) | |||
2045 | << formatv("{0:x}", DstRT.getKeyUnsafe()) << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << SrcRT.getJITDylib ().getName() << " transfering resources from tracker " << formatv("{0:x}", SrcRT.getKeyUnsafe()) << " to tracker " << formatv("{0:x}", DstRT.getKeyUnsafe()) << "\n" ; }; } } while (false) | |||
2046 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << SrcRT.getJITDylib ().getName() << " transfering resources from tracker " << formatv("{0:x}", SrcRT.getKeyUnsafe()) << " to tracker " << formatv("{0:x}", DstRT.getKeyUnsafe()) << "\n" ; }; } } while (false); | |||
2047 | ||||
2048 | // No-op transfers are allowed and do not invalidate the source. | |||
2049 | if (&DstRT == &SrcRT) | |||
2050 | return; | |||
2051 | ||||
2052 | assert(&DstRT.getJITDylib() == &SrcRT.getJITDylib() &&(static_cast <bool> (&DstRT.getJITDylib() == &SrcRT .getJITDylib() && "Can't transfer resources between JITDylibs" ) ? void (0) : __assert_fail ("&DstRT.getJITDylib() == &SrcRT.getJITDylib() && \"Can't transfer resources between JITDylibs\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2053, __extension__ __PRETTY_FUNCTION__)) | |||
2053 | "Can't transfer resources between JITDylibs")(static_cast <bool> (&DstRT.getJITDylib() == &SrcRT .getJITDylib() && "Can't transfer resources between JITDylibs" ) ? void (0) : __assert_fail ("&DstRT.getJITDylib() == &SrcRT.getJITDylib() && \"Can't transfer resources between JITDylibs\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2053, __extension__ __PRETTY_FUNCTION__)); | |||
2054 | runSessionLocked([&]() { | |||
2055 | SrcRT.makeDefunct(); | |||
2056 | auto &JD = DstRT.getJITDylib(); | |||
2057 | JD.transferTracker(DstRT, SrcRT); | |||
2058 | for (auto *L : reverse(ResourceManagers)) | |||
2059 | L->handleTransferResources(DstRT.getKeyUnsafe(), SrcRT.getKeyUnsafe()); | |||
2060 | }); | |||
2061 | } | |||
2062 | ||||
2063 | void ExecutionSession::destroyResourceTracker(ResourceTracker &RT) { | |||
2064 | runSessionLocked([&]() { | |||
2065 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << RT.getJITDylib(). getName() << " destroying tracker " << formatv("{0:x}" , RT.getKeyUnsafe()) << "\n"; }; } } while (false) | |||
2066 | dbgs() << "In " << RT.getJITDylib().getName() << " destroying tracker "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << RT.getJITDylib(). getName() << " destroying tracker " << formatv("{0:x}" , RT.getKeyUnsafe()) << "\n"; }; } } while (false) | |||
2067 | << formatv("{0:x}", RT.getKeyUnsafe()) << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << RT.getJITDylib(). getName() << " destroying tracker " << formatv("{0:x}" , RT.getKeyUnsafe()) << "\n"; }; } } while (false) | |||
2068 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << RT.getJITDylib(). getName() << " destroying tracker " << formatv("{0:x}" , RT.getKeyUnsafe()) << "\n"; }; } } while (false); | |||
2069 | if (!RT.isDefunct()) | |||
2070 | transferResourceTracker(*RT.getJITDylib().getDefaultResourceTracker(), | |||
2071 | RT); | |||
2072 | }); | |||
2073 | } | |||
2074 | ||||
2075 | Error ExecutionSession::IL_updateCandidatesFor( | |||
2076 | JITDylib &JD, JITDylibLookupFlags JDLookupFlags, | |||
2077 | SymbolLookupSet &Candidates, SymbolLookupSet *NonCandidates) { | |||
2078 | return Candidates.forEachWithRemoval( | |||
2079 | [&](const SymbolStringPtr &Name, | |||
2080 | SymbolLookupFlags SymLookupFlags) -> Expected<bool> { | |||
2081 | /// Search for the symbol. If not found then continue without | |||
2082 | /// removal. | |||
2083 | auto SymI = JD.Symbols.find(Name); | |||
2084 | if (SymI == JD.Symbols.end()) | |||
2085 | return false; | |||
2086 | ||||
2087 | // If this is a non-exported symbol and we're matching exported | |||
2088 | // symbols only then remove this symbol from the candidates list. | |||
2089 | // | |||
2090 | // If we're tracking non-candidates then add this to the non-candidate | |||
2091 | // list. | |||
2092 | if (!SymI->second.getFlags().isExported() && | |||
2093 | JDLookupFlags == JITDylibLookupFlags::MatchExportedSymbolsOnly) { | |||
2094 | if (NonCandidates) | |||
2095 | NonCandidates->add(Name, SymLookupFlags); | |||
2096 | return true; | |||
2097 | } | |||
2098 | ||||
2099 | // If we match against a materialization-side-effects only symbol | |||
2100 | // then make sure it is weakly-referenced. Otherwise bail out with | |||
2101 | // an error. | |||
2102 | // FIXME: Use a "materialization-side-effects-only symbols must be | |||
2103 | // weakly referenced" specific error here to reduce confusion. | |||
2104 | if (SymI->second.getFlags().hasMaterializationSideEffectsOnly() && | |||
2105 | SymLookupFlags != SymbolLookupFlags::WeaklyReferencedSymbol) | |||
2106 | return make_error<SymbolsNotFound>(SymbolNameVector({Name})); | |||
2107 | ||||
2108 | // If we matched against this symbol but it is in the error state | |||
2109 | // then bail out and treat it as a failure to materialize. | |||
2110 | if (SymI->second.getFlags().hasError()) { | |||
2111 | auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>(); | |||
2112 | (*FailedSymbolsMap)[&JD] = {Name}; | |||
2113 | return make_error<FailedToMaterialize>(std::move(FailedSymbolsMap)); | |||
2114 | } | |||
2115 | ||||
2116 | // Otherwise this is a match. Remove it from the candidate set. | |||
2117 | return true; | |||
2118 | }); | |||
2119 | } | |||
2120 | ||||
2121 | void ExecutionSession::OL_applyQueryPhase1( | |||
2122 | std::unique_ptr<InProgressLookupState> IPLS, Error Err) { | |||
2123 | ||||
2124 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_applyQueryPhase1:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2125 | dbgs() << "Entering OL_applyQueryPhase1:\n"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_applyQueryPhase1:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2126 | << " Lookup kind: " << IPLS->K << "\n"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_applyQueryPhase1:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2127 | << " Search order: " << IPLS->SearchOrderdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_applyQueryPhase1:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2128 | << ", Current index = " << IPLS->CurSearchOrderIndexdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_applyQueryPhase1:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2129 | << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_applyQueryPhase1:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2130 | << " Lookup set: " << IPLS->LookupSet << "\n"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_applyQueryPhase1:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2131 | << " Definition generator candidates: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_applyQueryPhase1:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2132 | << IPLS->DefGeneratorCandidates << "\n"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_applyQueryPhase1:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2133 | << " Definition generator non-candidates: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_applyQueryPhase1:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2134 | << IPLS->DefGeneratorNonCandidates << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_applyQueryPhase1:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2135 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_applyQueryPhase1:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false); | |||
2136 | ||||
2137 | // FIXME: We should attach the query as we go: This provides a result in a | |||
2138 | // single pass in the common case where all symbols have already reached the | |||
2139 | // required state. The query could be detached again in the 'fail' method on | |||
2140 | // IPLS. Phase 2 would be reduced to collecting and dispatching the MUs. | |||
2141 | ||||
2142 | while (IPLS->CurSearchOrderIndex != IPLS->SearchOrder.size()) { | |||
2143 | ||||
2144 | // If we've been handed an error or received one back from a generator then | |||
2145 | // fail the query. We don't need to unlink: At this stage the query hasn't | |||
2146 | // actually been lodged. | |||
2147 | if (Err) | |||
2148 | return IPLS->fail(std::move(Err)); | |||
2149 | ||||
2150 | // Get the next JITDylib and lookup flags. | |||
2151 | auto &KV = IPLS->SearchOrder[IPLS->CurSearchOrderIndex]; | |||
2152 | auto &JD = *KV.first; | |||
2153 | auto JDLookupFlags = KV.second; | |||
2154 | ||||
2155 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Visiting \"" << JD.getName () << "\" (" << JDLookupFlags << ") with lookup set " << IPLS->LookupSet << ":\n"; }; } } while (false ) | |||
2156 | dbgs() << "Visiting \"" << JD.getName() << "\" (" << JDLookupFlagsdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Visiting \"" << JD.getName () << "\" (" << JDLookupFlags << ") with lookup set " << IPLS->LookupSet << ":\n"; }; } } while (false ) | |||
2157 | << ") with lookup set " << IPLS->LookupSet << ":\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Visiting \"" << JD.getName () << "\" (" << JDLookupFlags << ") with lookup set " << IPLS->LookupSet << ":\n"; }; } } while (false ) | |||
2158 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Visiting \"" << JD.getName () << "\" (" << JDLookupFlags << ") with lookup set " << IPLS->LookupSet << ":\n"; }; } } while (false ); | |||
2159 | ||||
2160 | // If we've just reached a new JITDylib then perform some setup. | |||
2161 | if (IPLS->NewJITDylib) { | |||
2162 | ||||
2163 | // Acquire the generator lock for this JITDylib. | |||
2164 | IPLS->GeneratorLock = std::unique_lock<std::mutex>(JD.GeneratorsMutex); | |||
2165 | ||||
2166 | // Add any non-candidates from the last JITDylib (if any) back on to the | |||
2167 | // list of definition candidates for this JITDylib, reset definition | |||
2168 | // non-candiates to the empty set. | |||
2169 | SymbolLookupSet Tmp; | |||
2170 | std::swap(IPLS->DefGeneratorNonCandidates, Tmp); | |||
2171 | IPLS->DefGeneratorCandidates.append(std::move(Tmp)); | |||
2172 | ||||
2173 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " First time visiting " << JD.getName() << ", resetting candidate sets and building generator stack\n" ; }; } } while (false) | |||
2174 | dbgs() << " First time visiting " << JD.getName()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " First time visiting " << JD.getName() << ", resetting candidate sets and building generator stack\n" ; }; } } while (false) | |||
2175 | << ", resetting candidate sets and building generator stack\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " First time visiting " << JD.getName() << ", resetting candidate sets and building generator stack\n" ; }; } } while (false) | |||
2176 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " First time visiting " << JD.getName() << ", resetting candidate sets and building generator stack\n" ; }; } } while (false); | |||
2177 | ||||
2178 | // Build the definition generator stack for this JITDylib. | |||
2179 | for (auto &DG : reverse(JD.DefGenerators)) | |||
2180 | IPLS->CurDefGeneratorStack.push_back(DG); | |||
2181 | ||||
2182 | // Flag that we've done our initialization. | |||
2183 | IPLS->NewJITDylib = false; | |||
2184 | } | |||
2185 | ||||
2186 | // Remove any generation candidates that are already defined (and match) in | |||
2187 | // this JITDylib. | |||
2188 | runSessionLocked([&] { | |||
2189 | // Update the list of candidates (and non-candidates) for definition | |||
2190 | // generation. | |||
2191 | LLVM_DEBUG(dbgs() << " Updating candidate set...\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << " Updating candidate set...\n"; } } while (false); | |||
2192 | Err = IL_updateCandidatesFor( | |||
2193 | JD, JDLookupFlags, IPLS->DefGeneratorCandidates, | |||
2194 | JD.DefGenerators.empty() ? nullptr | |||
2195 | : &IPLS->DefGeneratorNonCandidates); | |||
2196 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " Remaining candidates = " << IPLS->DefGeneratorCandidates << "\n"; }; } } while ( false) | |||
2197 | dbgs() << " Remaining candidates = " << IPLS->DefGeneratorCandidatesdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " Remaining candidates = " << IPLS->DefGeneratorCandidates << "\n"; }; } } while ( false) | |||
2198 | << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " Remaining candidates = " << IPLS->DefGeneratorCandidates << "\n"; }; } } while ( false) | |||
2199 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " Remaining candidates = " << IPLS->DefGeneratorCandidates << "\n"; }; } } while ( false); | |||
2200 | }); | |||
2201 | ||||
2202 | // If we encountered an error while filtering generation candidates then | |||
2203 | // bail out. | |||
2204 | if (Err) | |||
2205 | return IPLS->fail(std::move(Err)); | |||
2206 | ||||
2207 | /// Apply any definition generators on the stack. | |||
2208 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { if (IPLS->CurDefGeneratorStack.empty()) do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType("orc" )) { dbgs() << " No generators to run for this JITDylib.\n" ; } } while (false); else if (IPLS->DefGeneratorCandidates .empty()) do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << " No candidates to generate.\n"; } } while (false); else dbgs() << " Running " << IPLS ->CurDefGeneratorStack.size() << " remaining generators for " << IPLS->DefGeneratorCandidates.size() << " candidates\n" ; }; } } while (false) | |||
2209 | if (IPLS->CurDefGeneratorStack.empty())do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { if (IPLS->CurDefGeneratorStack.empty()) do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType("orc" )) { dbgs() << " No generators to run for this JITDylib.\n" ; } } while (false); else if (IPLS->DefGeneratorCandidates .empty()) do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << " No candidates to generate.\n"; } } while (false); else dbgs() << " Running " << IPLS ->CurDefGeneratorStack.size() << " remaining generators for " << IPLS->DefGeneratorCandidates.size() << " candidates\n" ; }; } } while (false) | |||
2210 | LLVM_DEBUG(dbgs() << " No generators to run for this JITDylib.\n");do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { if (IPLS->CurDefGeneratorStack.empty()) do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType("orc" )) { dbgs() << " No generators to run for this JITDylib.\n" ; } } while (false); else if (IPLS->DefGeneratorCandidates .empty()) do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << " No candidates to generate.\n"; } } while (false); else dbgs() << " Running " << IPLS ->CurDefGeneratorStack.size() << " remaining generators for " << IPLS->DefGeneratorCandidates.size() << " candidates\n" ; }; } } while (false) | |||
2211 | else if (IPLS->DefGeneratorCandidates.empty())do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { if (IPLS->CurDefGeneratorStack.empty()) do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType("orc" )) { dbgs() << " No generators to run for this JITDylib.\n" ; } } while (false); else if (IPLS->DefGeneratorCandidates .empty()) do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << " No candidates to generate.\n"; } } while (false); else dbgs() << " Running " << IPLS ->CurDefGeneratorStack.size() << " remaining generators for " << IPLS->DefGeneratorCandidates.size() << " candidates\n" ; }; } } while (false) | |||
2212 | LLVM_DEBUG(dbgs() << " No candidates to generate.\n");do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { if (IPLS->CurDefGeneratorStack.empty()) do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType("orc" )) { dbgs() << " No generators to run for this JITDylib.\n" ; } } while (false); else if (IPLS->DefGeneratorCandidates .empty()) do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << " No candidates to generate.\n"; } } while (false); else dbgs() << " Running " << IPLS ->CurDefGeneratorStack.size() << " remaining generators for " << IPLS->DefGeneratorCandidates.size() << " candidates\n" ; }; } } while (false) | |||
2213 | elsedo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { if (IPLS->CurDefGeneratorStack.empty()) do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType("orc" )) { dbgs() << " No generators to run for this JITDylib.\n" ; } } while (false); else if (IPLS->DefGeneratorCandidates .empty()) do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << " No candidates to generate.\n"; } } while (false); else dbgs() << " Running " << IPLS ->CurDefGeneratorStack.size() << " remaining generators for " << IPLS->DefGeneratorCandidates.size() << " candidates\n" ; }; } } while (false) | |||
2214 | dbgs() << " Running " << IPLS->CurDefGeneratorStack.size()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { if (IPLS->CurDefGeneratorStack.empty()) do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType("orc" )) { dbgs() << " No generators to run for this JITDylib.\n" ; } } while (false); else if (IPLS->DefGeneratorCandidates .empty()) do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << " No candidates to generate.\n"; } } while (false); else dbgs() << " Running " << IPLS ->CurDefGeneratorStack.size() << " remaining generators for " << IPLS->DefGeneratorCandidates.size() << " candidates\n" ; }; } } while (false) | |||
2215 | << " remaining generators for "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { if (IPLS->CurDefGeneratorStack.empty()) do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType("orc" )) { dbgs() << " No generators to run for this JITDylib.\n" ; } } while (false); else if (IPLS->DefGeneratorCandidates .empty()) do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << " No candidates to generate.\n"; } } while (false); else dbgs() << " Running " << IPLS ->CurDefGeneratorStack.size() << " remaining generators for " << IPLS->DefGeneratorCandidates.size() << " candidates\n" ; }; } } while (false) | |||
2216 | << IPLS->DefGeneratorCandidates.size() << " candidates\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { if (IPLS->CurDefGeneratorStack.empty()) do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType("orc" )) { dbgs() << " No generators to run for this JITDylib.\n" ; } } while (false); else if (IPLS->DefGeneratorCandidates .empty()) do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << " No candidates to generate.\n"; } } while (false); else dbgs() << " Running " << IPLS ->CurDefGeneratorStack.size() << " remaining generators for " << IPLS->DefGeneratorCandidates.size() << " candidates\n" ; }; } } while (false) | |||
2217 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { if (IPLS->CurDefGeneratorStack.empty()) do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType("orc" )) { dbgs() << " No generators to run for this JITDylib.\n" ; } } while (false); else if (IPLS->DefGeneratorCandidates .empty()) do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << " No candidates to generate.\n"; } } while (false); else dbgs() << " Running " << IPLS ->CurDefGeneratorStack.size() << " remaining generators for " << IPLS->DefGeneratorCandidates.size() << " candidates\n" ; }; } } while (false); | |||
2218 | while (!IPLS->CurDefGeneratorStack.empty() && | |||
2219 | !IPLS->DefGeneratorCandidates.empty()) { | |||
2220 | auto DG = IPLS->CurDefGeneratorStack.back().lock(); | |||
2221 | IPLS->CurDefGeneratorStack.pop_back(); | |||
2222 | ||||
2223 | if (!DG) | |||
2224 | return IPLS->fail(make_error<StringError>( | |||
2225 | "DefinitionGenerator removed while lookup in progress", | |||
2226 | inconvertibleErrorCode())); | |||
2227 | ||||
2228 | auto K = IPLS->K; | |||
2229 | auto &LookupSet = IPLS->DefGeneratorCandidates; | |||
2230 | ||||
2231 | // Run the generator. If the generator takes ownership of QA then this | |||
2232 | // will break the loop. | |||
2233 | { | |||
2234 | LLVM_DEBUG(dbgs() << " Attempting to generate " << LookupSet << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << " Attempting to generate " << LookupSet << "\n"; } } while (false); | |||
2235 | LookupState LS(std::move(IPLS)); | |||
2236 | Err = DG->tryToGenerate(LS, K, JD, JDLookupFlags, LookupSet); | |||
2237 | IPLS = std::move(LS.IPLS); | |||
2238 | } | |||
2239 | ||||
2240 | // If there was an error then fail the query. | |||
2241 | if (Err) { | |||
2242 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " Error attempting to generate " << LookupSet << "\n"; }; } } while (false) | |||
2243 | dbgs() << " Error attempting to generate " << LookupSet << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " Error attempting to generate " << LookupSet << "\n"; }; } } while (false) | |||
2244 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " Error attempting to generate " << LookupSet << "\n"; }; } } while (false); | |||
2245 | assert(IPLS && "LS cannot be retained if error is returned")(static_cast <bool> (IPLS && "LS cannot be retained if error is returned" ) ? void (0) : __assert_fail ("IPLS && \"LS cannot be retained if error is returned\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2245, __extension__ __PRETTY_FUNCTION__)); | |||
2246 | return IPLS->fail(std::move(Err)); | |||
2247 | } | |||
2248 | ||||
2249 | // Otherwise if QA was captured then break the loop. | |||
2250 | if (!IPLS) { | |||
2251 | LLVM_DEBUG(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " LookupState captured. Exiting phase1 for now.\n" ; }; } } while (false) | |||
2252 | { dbgs() << " LookupState captured. Exiting phase1 for now.\n"; })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " LookupState captured. Exiting phase1 for now.\n" ; }; } } while (false); | |||
2253 | return; | |||
2254 | } | |||
2255 | ||||
2256 | // Otherwise if we're continuing around the loop then update candidates | |||
2257 | // for the next round. | |||
2258 | runSessionLocked([&] { | |||
2259 | LLVM_DEBUG(dbgs() << " Updating candidate set post-generation\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << " Updating candidate set post-generation\n" ; } } while (false); | |||
2260 | Err = IL_updateCandidatesFor( | |||
2261 | JD, JDLookupFlags, IPLS->DefGeneratorCandidates, | |||
2262 | JD.DefGenerators.empty() ? nullptr | |||
2263 | : &IPLS->DefGeneratorNonCandidates); | |||
2264 | }); | |||
2265 | ||||
2266 | // If updating candidates failed then fail the query. | |||
2267 | if (Err) { | |||
2268 | LLVM_DEBUG(dbgs() << " Error encountered while updating candidates\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << " Error encountered while updating candidates\n" ; } } while (false); | |||
2269 | return IPLS->fail(std::move(Err)); | |||
2270 | } | |||
2271 | } | |||
2272 | ||||
2273 | // If we get here then we've moved on to the next JITDylib. | |||
2274 | LLVM_DEBUG(dbgs() << "Phase 1 moving to next JITDylib.\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "Phase 1 moving to next JITDylib.\n" ; } } while (false); | |||
2275 | ++IPLS->CurSearchOrderIndex; | |||
2276 | IPLS->NewJITDylib = true; | |||
2277 | } | |||
2278 | ||||
2279 | // Remove any weakly referenced candidates that could not be found/generated. | |||
2280 | IPLS->DefGeneratorCandidates.remove_if( | |||
2281 | [](const SymbolStringPtr &Name, SymbolLookupFlags SymLookupFlags) { | |||
2282 | return SymLookupFlags == SymbolLookupFlags::WeaklyReferencedSymbol; | |||
2283 | }); | |||
2284 | ||||
2285 | // If we get here then we've finished searching all JITDylibs. | |||
2286 | // If we matched all symbols then move to phase 2, otherwise fail the query | |||
2287 | // with a SymbolsNotFound error. | |||
2288 | if (IPLS->DefGeneratorCandidates.empty()) { | |||
2289 | LLVM_DEBUG(dbgs() << "Phase 1 succeeded.\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "Phase 1 succeeded.\n"; } } while ( false); | |||
2290 | IPLS->complete(std::move(IPLS)); | |||
2291 | } else { | |||
2292 | LLVM_DEBUG(dbgs() << "Phase 1 failed with unresolved symbols.\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "Phase 1 failed with unresolved symbols.\n" ; } } while (false); | |||
2293 | IPLS->fail(make_error<SymbolsNotFound>( | |||
2294 | IPLS->DefGeneratorCandidates.getSymbolNames())); | |||
2295 | } | |||
2296 | } | |||
2297 | ||||
2298 | void ExecutionSession::OL_completeLookup( | |||
2299 | std::unique_ptr<InProgressLookupState> IPLS, | |||
2300 | std::shared_ptr<AsynchronousSymbolQuery> Q, | |||
2301 | RegisterDependenciesFunction RegisterDependencies) { | |||
2302 | ||||
2303 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookup:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS-> DefGeneratorNonCandidates << "\n"; }; } } while (false) | |||
2304 | dbgs() << "Entering OL_completeLookup:\n"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookup:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS-> DefGeneratorNonCandidates << "\n"; }; } } while (false) | |||
2305 | << " Lookup kind: " << IPLS->K << "\n"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookup:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS-> DefGeneratorNonCandidates << "\n"; }; } } while (false) | |||
2306 | << " Search order: " << IPLS->SearchOrderdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookup:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS-> DefGeneratorNonCandidates << "\n"; }; } } while (false) | |||
2307 | << ", Current index = " << IPLS->CurSearchOrderIndexdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookup:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS-> DefGeneratorNonCandidates << "\n"; }; } } while (false) | |||
2308 | << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookup:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS-> DefGeneratorNonCandidates << "\n"; }; } } while (false) | |||
2309 | << " Lookup set: " << IPLS->LookupSet << "\n"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookup:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS-> DefGeneratorNonCandidates << "\n"; }; } } while (false) | |||
2310 | << " Definition generator candidates: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookup:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS-> DefGeneratorNonCandidates << "\n"; }; } } while (false) | |||
2311 | << IPLS->DefGeneratorCandidates << "\n"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookup:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS-> DefGeneratorNonCandidates << "\n"; }; } } while (false) | |||
2312 | << " Definition generator non-candidates: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookup:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS-> DefGeneratorNonCandidates << "\n"; }; } } while (false) | |||
2313 | << IPLS->DefGeneratorNonCandidates << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookup:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS-> DefGeneratorNonCandidates << "\n"; }; } } while (false) | |||
2314 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookup:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS-> DefGeneratorNonCandidates << "\n"; }; } } while (false); | |||
2315 | ||||
2316 | bool QueryComplete = false; | |||
2317 | DenseMap<JITDylib *, JITDylib::UnmaterializedInfosList> CollectedUMIs; | |||
2318 | ||||
2319 | auto LodgingErr = runSessionLocked([&]() -> Error { | |||
2320 | for (auto &KV : IPLS->SearchOrder) { | |||
2321 | auto &JD = *KV.first; | |||
2322 | auto JDLookupFlags = KV.second; | |||
2323 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Visiting \"" << JD.getName () << "\" (" << JDLookupFlags << ") with lookup set " << IPLS->LookupSet << ":\n"; }; } } while (false ) | |||
2324 | dbgs() << "Visiting \"" << JD.getName() << "\" (" << JDLookupFlagsdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Visiting \"" << JD.getName () << "\" (" << JDLookupFlags << ") with lookup set " << IPLS->LookupSet << ":\n"; }; } } while (false ) | |||
2325 | << ") with lookup set " << IPLS->LookupSet << ":\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Visiting \"" << JD.getName () << "\" (" << JDLookupFlags << ") with lookup set " << IPLS->LookupSet << ":\n"; }; } } while (false ) | |||
2326 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Visiting \"" << JD.getName () << "\" (" << JDLookupFlags << ") with lookup set " << IPLS->LookupSet << ":\n"; }; } } while (false ); | |||
2327 | ||||
2328 | auto Err = IPLS->LookupSet.forEachWithRemoval( | |||
2329 | [&](const SymbolStringPtr &Name, | |||
2330 | SymbolLookupFlags SymLookupFlags) -> Expected<bool> { | |||
2331 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " Attempting to match \"" << Name << "\" (" << SymLookupFlags << ")... " ; }; } } while (false) | |||
2332 | dbgs() << " Attempting to match \"" << Name << "\" ("do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " Attempting to match \"" << Name << "\" (" << SymLookupFlags << ")... " ; }; } } while (false) | |||
2333 | << SymLookupFlags << ")... ";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " Attempting to match \"" << Name << "\" (" << SymLookupFlags << ")... " ; }; } } while (false) | |||
2334 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " Attempting to match \"" << Name << "\" (" << SymLookupFlags << ")... " ; }; } } while (false); | |||
2335 | ||||
2336 | /// Search for the symbol. If not found then continue without | |||
2337 | /// removal. | |||
2338 | auto SymI = JD.Symbols.find(Name); | |||
2339 | if (SymI == JD.Symbols.end()) { | |||
2340 | LLVM_DEBUG(dbgs() << "skipping: not present\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "skipping: not present\n"; } } while (false); | |||
2341 | return false; | |||
2342 | } | |||
2343 | ||||
2344 | // If this is a non-exported symbol and we're matching exported | |||
2345 | // symbols only then skip this symbol without removal. | |||
2346 | if (!SymI->second.getFlags().isExported() && | |||
2347 | JDLookupFlags == | |||
2348 | JITDylibLookupFlags::MatchExportedSymbolsOnly) { | |||
2349 | LLVM_DEBUG(dbgs() << "skipping: not exported\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "skipping: not exported\n"; } } while (false); | |||
2350 | return false; | |||
2351 | } | |||
2352 | ||||
2353 | // If we match against a materialization-side-effects only symbol | |||
2354 | // then make sure it is weakly-referenced. Otherwise bail out with | |||
2355 | // an error. | |||
2356 | // FIXME: Use a "materialization-side-effects-only symbols must be | |||
2357 | // weakly referenced" specific error here to reduce confusion. | |||
2358 | if (SymI->second.getFlags().hasMaterializationSideEffectsOnly() && | |||
2359 | SymLookupFlags != SymbolLookupFlags::WeaklyReferencedSymbol) { | |||
2360 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "error: " "required, but symbol is has-side-effects-only\n" ; }; } } while (false) | |||
2361 | dbgs() << "error: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "error: " "required, but symbol is has-side-effects-only\n" ; }; } } while (false) | |||
2362 | "required, but symbol is has-side-effects-only\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "error: " "required, but symbol is has-side-effects-only\n" ; }; } } while (false) | |||
2363 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "error: " "required, but symbol is has-side-effects-only\n" ; }; } } while (false); | |||
2364 | return make_error<SymbolsNotFound>(SymbolNameVector({Name})); | |||
2365 | } | |||
2366 | ||||
2367 | // If we matched against this symbol but it is in the error state | |||
2368 | // then bail out and treat it as a failure to materialize. | |||
2369 | if (SymI->second.getFlags().hasError()) { | |||
2370 | LLVM_DEBUG(dbgs() << "error: symbol is in error state\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "error: symbol is in error state\n" ; } } while (false); | |||
2371 | auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>(); | |||
2372 | (*FailedSymbolsMap)[&JD] = {Name}; | |||
2373 | return make_error<FailedToMaterialize>( | |||
2374 | std::move(FailedSymbolsMap)); | |||
2375 | } | |||
2376 | ||||
2377 | // Otherwise this is a match. | |||
2378 | ||||
2379 | // If this symbol is already in the requried state then notify the | |||
2380 | // query, remove the symbol and continue. | |||
2381 | if (SymI->second.getState() >= Q->getRequiredState()) { | |||
2382 | LLVM_DEBUG(dbgs()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "matched, symbol already in required state\n" ; } } while (false) | |||
2383 | << "matched, symbol already in required state\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "matched, symbol already in required state\n" ; } } while (false); | |||
2384 | Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol()); | |||
2385 | return true; | |||
2386 | } | |||
2387 | ||||
2388 | // Otherwise this symbol does not yet meet the required state. Check | |||
2389 | // whether it has a materializer attached, and if so prepare to run | |||
2390 | // it. | |||
2391 | if (SymI->second.hasMaterializerAttached()) { | |||
2392 | assert(SymI->second.getAddress() == 0 &&(static_cast <bool> (SymI->second.getAddress() == 0 && "Symbol not resolved but already has address?") ? void (0) : __assert_fail ("SymI->second.getAddress() == 0 && \"Symbol not resolved but already has address?\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2393, __extension__ __PRETTY_FUNCTION__)) | |||
2393 | "Symbol not resolved but already has address?")(static_cast <bool> (SymI->second.getAddress() == 0 && "Symbol not resolved but already has address?") ? void (0) : __assert_fail ("SymI->second.getAddress() == 0 && \"Symbol not resolved but already has address?\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2393, __extension__ __PRETTY_FUNCTION__)); | |||
2394 | auto UMII = JD.UnmaterializedInfos.find(Name); | |||
2395 | assert(UMII != JD.UnmaterializedInfos.end() &&(static_cast <bool> (UMII != JD.UnmaterializedInfos.end () && "Lazy symbol should have UnmaterializedInfo") ? void (0) : __assert_fail ("UMII != JD.UnmaterializedInfos.end() && \"Lazy symbol should have UnmaterializedInfo\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2396, __extension__ __PRETTY_FUNCTION__)) | |||
2396 | "Lazy symbol should have UnmaterializedInfo")(static_cast <bool> (UMII != JD.UnmaterializedInfos.end () && "Lazy symbol should have UnmaterializedInfo") ? void (0) : __assert_fail ("UMII != JD.UnmaterializedInfos.end() && \"Lazy symbol should have UnmaterializedInfo\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2396, __extension__ __PRETTY_FUNCTION__)); | |||
2397 | ||||
2398 | auto UMI = UMII->second; | |||
2399 | assert(UMI->MU && "Materializer should not be null")(static_cast <bool> (UMI->MU && "Materializer should not be null" ) ? void (0) : __assert_fail ("UMI->MU && \"Materializer should not be null\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2399, __extension__ __PRETTY_FUNCTION__)); | |||
2400 | assert(UMI->RT && "Tracker should not be null")(static_cast <bool> (UMI->RT && "Tracker should not be null" ) ? void (0) : __assert_fail ("UMI->RT && \"Tracker should not be null\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2400, __extension__ __PRETTY_FUNCTION__)); | |||
2401 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "matched, preparing to dispatch MU@" << UMI->MU.get() << " (" << UMI->MU-> getName() << ")\n"; }; } } while (false) | |||
2402 | dbgs() << "matched, preparing to dispatch MU@" << UMI->MU.get()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "matched, preparing to dispatch MU@" << UMI->MU.get() << " (" << UMI->MU-> getName() << ")\n"; }; } } while (false) | |||
2403 | << " (" << UMI->MU->getName() << ")\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "matched, preparing to dispatch MU@" << UMI->MU.get() << " (" << UMI->MU-> getName() << ")\n"; }; } } while (false) | |||
2404 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "matched, preparing to dispatch MU@" << UMI->MU.get() << " (" << UMI->MU-> getName() << ")\n"; }; } } while (false); | |||
2405 | ||||
2406 | // Move all symbols associated with this MaterializationUnit into | |||
2407 | // materializing state. | |||
2408 | for (auto &KV : UMI->MU->getSymbols()) { | |||
2409 | auto SymK = JD.Symbols.find(KV.first); | |||
2410 | assert(SymK != JD.Symbols.end() &&(static_cast <bool> (SymK != JD.Symbols.end() && "No entry for symbol covered by MaterializationUnit") ? void (0) : __assert_fail ("SymK != JD.Symbols.end() && \"No entry for symbol covered by MaterializationUnit\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2411, __extension__ __PRETTY_FUNCTION__)) | |||
2411 | "No entry for symbol covered by MaterializationUnit")(static_cast <bool> (SymK != JD.Symbols.end() && "No entry for symbol covered by MaterializationUnit") ? void (0) : __assert_fail ("SymK != JD.Symbols.end() && \"No entry for symbol covered by MaterializationUnit\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2411, __extension__ __PRETTY_FUNCTION__)); | |||
2412 | SymK->second.setMaterializerAttached(false); | |||
2413 | SymK->second.setState(SymbolState::Materializing); | |||
2414 | JD.UnmaterializedInfos.erase(KV.first); | |||
2415 | } | |||
2416 | ||||
2417 | // Add MU to the list of MaterializationUnits to be materialized. | |||
2418 | CollectedUMIs[&JD].push_back(std::move(UMI)); | |||
2419 | } else | |||
2420 | LLVM_DEBUG(dbgs() << "matched, registering query")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "matched, registering query"; } } while (false); | |||
2421 | ||||
2422 | // Add the query to the PendingQueries list and continue, deleting | |||
2423 | // the element from the lookup set. | |||
2424 | assert(SymI->second.getState() != SymbolState::NeverSearched &&(static_cast <bool> (SymI->second.getState() != SymbolState ::NeverSearched && SymI->second.getState() != SymbolState ::Ready && "By this line the symbol should be materializing" ) ? void (0) : __assert_fail ("SymI->second.getState() != SymbolState::NeverSearched && SymI->second.getState() != SymbolState::Ready && \"By this line the symbol should be materializing\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2426, __extension__ __PRETTY_FUNCTION__)) | |||
2425 | SymI->second.getState() != SymbolState::Ready &&(static_cast <bool> (SymI->second.getState() != SymbolState ::NeverSearched && SymI->second.getState() != SymbolState ::Ready && "By this line the symbol should be materializing" ) ? void (0) : __assert_fail ("SymI->second.getState() != SymbolState::NeverSearched && SymI->second.getState() != SymbolState::Ready && \"By this line the symbol should be materializing\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2426, __extension__ __PRETTY_FUNCTION__)) | |||
2426 | "By this line the symbol should be materializing")(static_cast <bool> (SymI->second.getState() != SymbolState ::NeverSearched && SymI->second.getState() != SymbolState ::Ready && "By this line the symbol should be materializing" ) ? void (0) : __assert_fail ("SymI->second.getState() != SymbolState::NeverSearched && SymI->second.getState() != SymbolState::Ready && \"By this line the symbol should be materializing\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2426, __extension__ __PRETTY_FUNCTION__)); | |||
2427 | auto &MI = JD.MaterializingInfos[Name]; | |||
2428 | MI.addQuery(Q); | |||
2429 | Q->addQueryDependence(JD, Name); | |||
2430 | ||||
2431 | return true; | |||
2432 | }); | |||
2433 | ||||
2434 | // Handle failure. | |||
2435 | if (Err) { | |||
2436 | ||||
2437 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Lookup failed. Detaching query and replacing MUs.\n" ; }; } } while (false) | |||
2438 | dbgs() << "Lookup failed. Detaching query and replacing MUs.\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Lookup failed. Detaching query and replacing MUs.\n" ; }; } } while (false) | |||
2439 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Lookup failed. Detaching query and replacing MUs.\n" ; }; } } while (false); | |||
2440 | ||||
2441 | // Detach the query. | |||
2442 | Q->detach(); | |||
2443 | ||||
2444 | // Replace the MUs. | |||
2445 | for (auto &KV : CollectedUMIs) { | |||
2446 | auto &JD = *KV.first; | |||
2447 | for (auto &UMI : KV.second) | |||
2448 | for (auto &KV2 : UMI->MU->getSymbols()) { | |||
2449 | assert(!JD.UnmaterializedInfos.count(KV2.first) &&(static_cast <bool> (!JD.UnmaterializedInfos.count(KV2. first) && "Unexpected materializer in map") ? void (0 ) : __assert_fail ("!JD.UnmaterializedInfos.count(KV2.first) && \"Unexpected materializer in map\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2450, __extension__ __PRETTY_FUNCTION__)) | |||
2450 | "Unexpected materializer in map")(static_cast <bool> (!JD.UnmaterializedInfos.count(KV2. first) && "Unexpected materializer in map") ? void (0 ) : __assert_fail ("!JD.UnmaterializedInfos.count(KV2.first) && \"Unexpected materializer in map\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2450, __extension__ __PRETTY_FUNCTION__)); | |||
2451 | auto SymI = JD.Symbols.find(KV2.first); | |||
2452 | assert(SymI != JD.Symbols.end() && "Missing symbol entry")(static_cast <bool> (SymI != JD.Symbols.end() && "Missing symbol entry") ? void (0) : __assert_fail ("SymI != JD.Symbols.end() && \"Missing symbol entry\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2452, __extension__ __PRETTY_FUNCTION__)); | |||
2453 | assert(SymI->second.getState() == SymbolState::Materializing &&(static_cast <bool> (SymI->second.getState() == SymbolState ::Materializing && "Can not replace symbol that is not materializing" ) ? void (0) : __assert_fail ("SymI->second.getState() == SymbolState::Materializing && \"Can not replace symbol that is not materializing\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2454, __extension__ __PRETTY_FUNCTION__)) | |||
2454 | "Can not replace symbol that is not materializing")(static_cast <bool> (SymI->second.getState() == SymbolState ::Materializing && "Can not replace symbol that is not materializing" ) ? void (0) : __assert_fail ("SymI->second.getState() == SymbolState::Materializing && \"Can not replace symbol that is not materializing\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2454, __extension__ __PRETTY_FUNCTION__)); | |||
2455 | assert(!SymI->second.hasMaterializerAttached() &&(static_cast <bool> (!SymI->second.hasMaterializerAttached () && "MaterializerAttached flag should not be set") ? void (0) : __assert_fail ("!SymI->second.hasMaterializerAttached() && \"MaterializerAttached flag should not be set\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2456, __extension__ __PRETTY_FUNCTION__)) | |||
2456 | "MaterializerAttached flag should not be set")(static_cast <bool> (!SymI->second.hasMaterializerAttached () && "MaterializerAttached flag should not be set") ? void (0) : __assert_fail ("!SymI->second.hasMaterializerAttached() && \"MaterializerAttached flag should not be set\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2456, __extension__ __PRETTY_FUNCTION__)); | |||
2457 | SymI->second.setMaterializerAttached(true); | |||
2458 | JD.UnmaterializedInfos[KV2.first] = UMI; | |||
2459 | } | |||
2460 | } | |||
2461 | ||||
2462 | return Err; | |||
2463 | } | |||
2464 | } | |||
2465 | ||||
2466 | LLVM_DEBUG(dbgs() << "Stripping unmatched weakly-refererced symbols\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "Stripping unmatched weakly-refererced symbols\n" ; } } while (false); | |||
2467 | IPLS->LookupSet.forEachWithRemoval( | |||
2468 | [&](const SymbolStringPtr &Name, SymbolLookupFlags SymLookupFlags) { | |||
2469 | if (SymLookupFlags == SymbolLookupFlags::WeaklyReferencedSymbol) { | |||
2470 | Q->dropSymbol(Name); | |||
2471 | return true; | |||
2472 | } else | |||
2473 | return false; | |||
2474 | }); | |||
2475 | ||||
2476 | if (!IPLS->LookupSet.empty()) { | |||
2477 | LLVM_DEBUG(dbgs() << "Failing due to unresolved symbols\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "Failing due to unresolved symbols\n" ; } } while (false); | |||
2478 | return make_error<SymbolsNotFound>(IPLS->LookupSet.getSymbolNames()); | |||
2479 | } | |||
2480 | ||||
2481 | // Record whether the query completed. | |||
2482 | QueryComplete = Q->isComplete(); | |||
2483 | ||||
2484 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Query successfully " << ( QueryComplete ? "completed" : "lodged") << "\n"; }; } } while (false) | |||
2485 | dbgs() << "Query successfully "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Query successfully " << ( QueryComplete ? "completed" : "lodged") << "\n"; }; } } while (false) | |||
2486 | << (QueryComplete ? "completed" : "lodged") << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Query successfully " << ( QueryComplete ? "completed" : "lodged") << "\n"; }; } } while (false) | |||
2487 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Query successfully " << ( QueryComplete ? "completed" : "lodged") << "\n"; }; } } while (false); | |||
2488 | ||||
2489 | // Move the collected MUs to the OutstandingMUs list. | |||
2490 | if (!CollectedUMIs.empty()) { | |||
2491 | std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex); | |||
2492 | ||||
2493 | LLVM_DEBUG(dbgs() << "Adding MUs to dispatch:\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "Adding MUs to dispatch:\n"; } } while (false); | |||
2494 | for (auto &KV : CollectedUMIs) { | |||
2495 | auto &JD = *KV.first; | |||
2496 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " For " << JD.getName() << ": Adding " << KV.second.size() << " MUs.\n"; }; } } while (false) | |||
2497 | dbgs() << " For " << JD.getName() << ": Adding " << KV.second.size()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " For " << JD.getName() << ": Adding " << KV.second.size() << " MUs.\n"; }; } } while (false) | |||
2498 | << " MUs.\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " For " << JD.getName() << ": Adding " << KV.second.size() << " MUs.\n"; }; } } while (false) | |||
2499 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " For " << JD.getName() << ": Adding " << KV.second.size() << " MUs.\n"; }; } } while (false); | |||
2500 | for (auto &UMI : KV.second) { | |||
2501 | std::unique_ptr<MaterializationResponsibility> MR( | |||
2502 | new MaterializationResponsibility( | |||
2503 | &JD, std::move(UMI->MU->SymbolFlags), | |||
2504 | std::move(UMI->MU->InitSymbol))); | |||
2505 | JD.MRTrackers[MR.get()] = UMI->RT; | |||
2506 | OutstandingMUs.push_back( | |||
2507 | std::make_pair(std::move(UMI->MU), std::move(MR))); | |||
2508 | } | |||
2509 | } | |||
2510 | } else | |||
2511 | LLVM_DEBUG(dbgs() << "No MUs to dispatch.\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "No MUs to dispatch.\n"; } } while (false); | |||
2512 | ||||
2513 | if (RegisterDependencies && !Q->QueryRegistrations.empty()) { | |||
2514 | LLVM_DEBUG(dbgs() << "Registering dependencies\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "Registering dependencies\n"; } } while (false); | |||
2515 | RegisterDependencies(Q->QueryRegistrations); | |||
2516 | } else | |||
2517 | LLVM_DEBUG(dbgs() << "No dependencies to register\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "No dependencies to register\n"; } } while (false); | |||
2518 | ||||
2519 | return Error::success(); | |||
2520 | }); | |||
2521 | ||||
2522 | if (LodgingErr) { | |||
2523 | LLVM_DEBUG(dbgs() << "Failing query\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "Failing query\n"; } } while (false ); | |||
2524 | Q->detach(); | |||
2525 | Q->handleFailed(std::move(LodgingErr)); | |||
2526 | return; | |||
2527 | } | |||
2528 | ||||
2529 | if (QueryComplete) { | |||
2530 | LLVM_DEBUG(dbgs() << "Completing query\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "Completing query\n"; } } while (false ); | |||
2531 | Q->handleComplete(); | |||
2532 | } | |||
2533 | ||||
2534 | dispatchOutstandingMUs(); | |||
2535 | } | |||
2536 | ||||
2537 | void ExecutionSession::OL_completeLookupFlags( | |||
2538 | std::unique_ptr<InProgressLookupState> IPLS, | |||
2539 | unique_function<void(Expected<SymbolFlagsMap>)> OnComplete) { | |||
2540 | ||||
2541 | auto Result = runSessionLocked([&]() -> Expected<SymbolFlagsMap> { | |||
2542 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookupFlags:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2543 | dbgs() << "Entering OL_completeLookupFlags:\n"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookupFlags:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2544 | << " Lookup kind: " << IPLS->K << "\n"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookupFlags:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2545 | << " Search order: " << IPLS->SearchOrderdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookupFlags:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2546 | << ", Current index = " << IPLS->CurSearchOrderIndexdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookupFlags:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2547 | << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookupFlags:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2548 | << " Lookup set: " << IPLS->LookupSet << "\n"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookupFlags:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2549 | << " Definition generator candidates: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookupFlags:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2550 | << IPLS->DefGeneratorCandidates << "\n"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookupFlags:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2551 | << " Definition generator non-candidates: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookupFlags:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2552 | << IPLS->DefGeneratorNonCandidates << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookupFlags:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false) | |||
2553 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Entering OL_completeLookupFlags:\n" << " Lookup kind: " << IPLS->K << "\n" << " Search order: " << IPLS->SearchOrder << ", Current index = " << IPLS->CurSearchOrderIndex << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n" << " Lookup set: " << IPLS->LookupSet << "\n" << " Definition generator candidates: " << IPLS->DefGeneratorCandidates << "\n" << " Definition generator non-candidates: " << IPLS->DefGeneratorNonCandidates << "\n"; } ; } } while (false); | |||
2554 | ||||
2555 | SymbolFlagsMap Result; | |||
2556 | ||||
2557 | // Attempt to find flags for each symbol. | |||
2558 | for (auto &KV : IPLS->SearchOrder) { | |||
2559 | auto &JD = *KV.first; | |||
2560 | auto JDLookupFlags = KV.second; | |||
2561 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Visiting \"" << JD.getName () << "\" (" << JDLookupFlags << ") with lookup set " << IPLS->LookupSet << ":\n"; }; } } while (false ) | |||
2562 | dbgs() << "Visiting \"" << JD.getName() << "\" (" << JDLookupFlagsdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Visiting \"" << JD.getName () << "\" (" << JDLookupFlags << ") with lookup set " << IPLS->LookupSet << ":\n"; }; } } while (false ) | |||
2563 | << ") with lookup set " << IPLS->LookupSet << ":\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Visiting \"" << JD.getName () << "\" (" << JDLookupFlags << ") with lookup set " << IPLS->LookupSet << ":\n"; }; } } while (false ) | |||
2564 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Visiting \"" << JD.getName () << "\" (" << JDLookupFlags << ") with lookup set " << IPLS->LookupSet << ":\n"; }; } } while (false ); | |||
2565 | ||||
2566 | IPLS->LookupSet.forEachWithRemoval([&](const SymbolStringPtr &Name, | |||
2567 | SymbolLookupFlags SymLookupFlags) { | |||
2568 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " Attempting to match \"" << Name << "\" (" << SymLookupFlags << ")... " ; }; } } while (false) | |||
2569 | dbgs() << " Attempting to match \"" << Name << "\" ("do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " Attempting to match \"" << Name << "\" (" << SymLookupFlags << ")... " ; }; } } while (false) | |||
2570 | << SymLookupFlags << ")... ";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " Attempting to match \"" << Name << "\" (" << SymLookupFlags << ")... " ; }; } } while (false) | |||
2571 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << " Attempting to match \"" << Name << "\" (" << SymLookupFlags << ")... " ; }; } } while (false); | |||
2572 | ||||
2573 | // Search for the symbol. If not found then continue without removing | |||
2574 | // from the lookup set. | |||
2575 | auto SymI = JD.Symbols.find(Name); | |||
2576 | if (SymI == JD.Symbols.end()) { | |||
2577 | LLVM_DEBUG(dbgs() << "skipping: not present\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "skipping: not present\n"; } } while (false); | |||
2578 | return false; | |||
2579 | } | |||
2580 | ||||
2581 | // If this is a non-exported symbol then it doesn't match. Skip it. | |||
2582 | if (!SymI->second.getFlags().isExported() && | |||
2583 | JDLookupFlags == JITDylibLookupFlags::MatchExportedSymbolsOnly) { | |||
2584 | LLVM_DEBUG(dbgs() << "skipping: not exported\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "skipping: not exported\n"; } } while (false); | |||
2585 | return false; | |||
2586 | } | |||
2587 | ||||
2588 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "matched, \"" << Name << "\" -> " << SymI->second.getFlags() << "\n" ; }; } } while (false) | |||
2589 | dbgs() << "matched, \"" << Name << "\" -> " << SymI->second.getFlags()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "matched, \"" << Name << "\" -> " << SymI->second.getFlags() << "\n" ; }; } } while (false) | |||
2590 | << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "matched, \"" << Name << "\" -> " << SymI->second.getFlags() << "\n" ; }; } } while (false) | |||
2591 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "matched, \"" << Name << "\" -> " << SymI->second.getFlags() << "\n" ; }; } } while (false); | |||
2592 | Result[Name] = SymI->second.getFlags(); | |||
2593 | return true; | |||
2594 | }); | |||
2595 | } | |||
2596 | ||||
2597 | // Remove any weakly referenced symbols that haven't been resolved. | |||
2598 | IPLS->LookupSet.remove_if( | |||
2599 | [](const SymbolStringPtr &Name, SymbolLookupFlags SymLookupFlags) { | |||
2600 | return SymLookupFlags == SymbolLookupFlags::WeaklyReferencedSymbol; | |||
2601 | }); | |||
2602 | ||||
2603 | if (!IPLS->LookupSet.empty()) { | |||
2604 | LLVM_DEBUG(dbgs() << "Failing due to unresolved symbols\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "Failing due to unresolved symbols\n" ; } } while (false); | |||
2605 | return make_error<SymbolsNotFound>(IPLS->LookupSet.getSymbolNames()); | |||
2606 | } | |||
2607 | ||||
2608 | LLVM_DEBUG(dbgs() << "Succeded, result = " << Result << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "Succeded, result = " << Result << "\n"; } } while (false); | |||
2609 | return Result; | |||
2610 | }); | |||
2611 | ||||
2612 | // Run the callback on the result. | |||
2613 | LLVM_DEBUG(dbgs() << "Sending result to handler.\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dbgs() << "Sending result to handler.\n"; } } while (false); | |||
2614 | OnComplete(std::move(Result)); | |||
2615 | } | |||
2616 | ||||
2617 | void ExecutionSession::OL_destroyMaterializationResponsibility( | |||
2618 | MaterializationResponsibility &MR) { | |||
2619 | ||||
2620 | assert(MR.SymbolFlags.empty() &&(static_cast <bool> (MR.SymbolFlags.empty() && "All symbols should have been explicitly materialized or failed" ) ? void (0) : __assert_fail ("MR.SymbolFlags.empty() && \"All symbols should have been explicitly materialized or failed\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2621, __extension__ __PRETTY_FUNCTION__)) | |||
2621 | "All symbols should have been explicitly materialized or failed")(static_cast <bool> (MR.SymbolFlags.empty() && "All symbols should have been explicitly materialized or failed" ) ? void (0) : __assert_fail ("MR.SymbolFlags.empty() && \"All symbols should have been explicitly materialized or failed\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2621, __extension__ __PRETTY_FUNCTION__)); | |||
2622 | MR.JD->unlinkMaterializationResponsibility(MR); | |||
2623 | } | |||
2624 | ||||
2625 | SymbolNameSet ExecutionSession::OL_getRequestedSymbols( | |||
2626 | const MaterializationResponsibility &MR) { | |||
2627 | return MR.JD->getRequestedSymbols(MR.SymbolFlags); | |||
2628 | } | |||
2629 | ||||
2630 | Error ExecutionSession::OL_notifyResolved(MaterializationResponsibility &MR, | |||
2631 | const SymbolMap &Symbols) { | |||
2632 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << MR.JD->getName () << " resolving " << Symbols << "\n"; }; } } while (false) | |||
2633 | dbgs() << "In " << MR.JD->getName() << " resolving " << Symbols << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << MR.JD->getName () << " resolving " << Symbols << "\n"; }; } } while (false) | |||
2634 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << MR.JD->getName () << " resolving " << Symbols << "\n"; }; } } while (false); | |||
2635 | #ifndef NDEBUG | |||
2636 | for (auto &KV : Symbols) { | |||
2637 | auto WeakFlags = JITSymbolFlags::Weak | JITSymbolFlags::Common; | |||
2638 | auto I = MR.SymbolFlags.find(KV.first); | |||
2639 | assert(I != MR.SymbolFlags.end() &&(static_cast <bool> (I != MR.SymbolFlags.end() && "Resolving symbol outside this responsibility set") ? void ( 0) : __assert_fail ("I != MR.SymbolFlags.end() && \"Resolving symbol outside this responsibility set\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2640, __extension__ __PRETTY_FUNCTION__)) | |||
2640 | "Resolving symbol outside this responsibility set")(static_cast <bool> (I != MR.SymbolFlags.end() && "Resolving symbol outside this responsibility set") ? void ( 0) : __assert_fail ("I != MR.SymbolFlags.end() && \"Resolving symbol outside this responsibility set\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2640, __extension__ __PRETTY_FUNCTION__)); | |||
2641 | assert(!I->second.hasMaterializationSideEffectsOnly() &&(static_cast <bool> (!I->second.hasMaterializationSideEffectsOnly () && "Can't resolve materialization-side-effects-only symbol" ) ? void (0) : __assert_fail ("!I->second.hasMaterializationSideEffectsOnly() && \"Can't resolve materialization-side-effects-only symbol\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2642, __extension__ __PRETTY_FUNCTION__)) | |||
2642 | "Can't resolve materialization-side-effects-only symbol")(static_cast <bool> (!I->second.hasMaterializationSideEffectsOnly () && "Can't resolve materialization-side-effects-only symbol" ) ? void (0) : __assert_fail ("!I->second.hasMaterializationSideEffectsOnly() && \"Can't resolve materialization-side-effects-only symbol\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2642, __extension__ __PRETTY_FUNCTION__)); | |||
2643 | assert((KV.second.getFlags() & ~WeakFlags) == (I->second & ~WeakFlags) &&(static_cast <bool> ((KV.second.getFlags() & ~WeakFlags ) == (I->second & ~WeakFlags) && "Resolving symbol with incorrect flags" ) ? void (0) : __assert_fail ("(KV.second.getFlags() & ~WeakFlags) == (I->second & ~WeakFlags) && \"Resolving symbol with incorrect flags\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2644, __extension__ __PRETTY_FUNCTION__)) | |||
2644 | "Resolving symbol with incorrect flags")(static_cast <bool> ((KV.second.getFlags() & ~WeakFlags ) == (I->second & ~WeakFlags) && "Resolving symbol with incorrect flags" ) ? void (0) : __assert_fail ("(KV.second.getFlags() & ~WeakFlags) == (I->second & ~WeakFlags) && \"Resolving symbol with incorrect flags\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2644, __extension__ __PRETTY_FUNCTION__)); | |||
2645 | } | |||
2646 | #endif | |||
2647 | ||||
2648 | return MR.JD->resolve(MR, Symbols); | |||
2649 | } | |||
2650 | ||||
2651 | Error ExecutionSession::OL_notifyEmitted(MaterializationResponsibility &MR) { | |||
2652 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << MR.JD->getName () << " emitting " << MR.SymbolFlags << "\n" ; }; } } while (false) | |||
2653 | dbgs() << "In " << MR.JD->getName() << " emitting " << MR.SymbolFlags << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << MR.JD->getName () << " emitting " << MR.SymbolFlags << "\n" ; }; } } while (false) | |||
2654 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << MR.JD->getName () << " emitting " << MR.SymbolFlags << "\n" ; }; } } while (false); | |||
2655 | ||||
2656 | if (auto Err = MR.JD->emit(MR, MR.SymbolFlags)) | |||
2657 | return Err; | |||
2658 | ||||
2659 | MR.SymbolFlags.clear(); | |||
2660 | return Error::success(); | |||
2661 | } | |||
2662 | ||||
2663 | Error ExecutionSession::OL_defineMaterializing( | |||
2664 | MaterializationResponsibility &MR, SymbolFlagsMap NewSymbolFlags) { | |||
2665 | ||||
2666 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << MR.JD->getName () << " defining materializing symbols " << NewSymbolFlags << "\n"; }; } } while (false) | |||
2667 | dbgs() << "In " << MR.JD->getName() << " defining materializing symbols "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << MR.JD->getName () << " defining materializing symbols " << NewSymbolFlags << "\n"; }; } } while (false) | |||
2668 | << NewSymbolFlags << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << MR.JD->getName () << " defining materializing symbols " << NewSymbolFlags << "\n"; }; } } while (false) | |||
2669 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << MR.JD->getName () << " defining materializing symbols " << NewSymbolFlags << "\n"; }; } } while (false); | |||
2670 | if (auto AcceptedDefs = MR.JD->defineMaterializing(std::move(NewSymbolFlags))) { | |||
2671 | // Add all newly accepted symbols to this responsibility object. | |||
2672 | for (auto &KV : *AcceptedDefs) | |||
2673 | MR.SymbolFlags.insert(KV); | |||
2674 | return Error::success(); | |||
2675 | } else | |||
2676 | return AcceptedDefs.takeError(); | |||
2677 | } | |||
2678 | ||||
2679 | void ExecutionSession::OL_notifyFailed(MaterializationResponsibility &MR) { | |||
2680 | ||||
2681 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << MR.JD->getName () << " failing materialization for " << MR.SymbolFlags << "\n"; }; } } while (false) | |||
2682 | dbgs() << "In " << MR.JD->getName() << " failing materialization for "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << MR.JD->getName () << " failing materialization for " << MR.SymbolFlags << "\n"; }; } } while (false) | |||
2683 | << MR.SymbolFlags << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << MR.JD->getName () << " failing materialization for " << MR.SymbolFlags << "\n"; }; } } while (false) | |||
2684 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "In " << MR.JD->getName () << " failing materialization for " << MR.SymbolFlags << "\n"; }; } } while (false); | |||
2685 | ||||
2686 | JITDylib::FailedSymbolsWorklist Worklist; | |||
2687 | ||||
2688 | for (auto &KV : MR.SymbolFlags) | |||
2689 | Worklist.push_back(std::make_pair(MR.JD.get(), KV.first)); | |||
2690 | MR.SymbolFlags.clear(); | |||
2691 | ||||
2692 | if (Worklist.empty()) | |||
2693 | return; | |||
2694 | ||||
2695 | JITDylib::AsynchronousSymbolQuerySet FailedQueries; | |||
2696 | std::shared_ptr<SymbolDependenceMap> FailedSymbols; | |||
2697 | ||||
2698 | runSessionLocked([&]() { | |||
2699 | auto RTI = MR.JD->MRTrackers.find(&MR); | |||
2700 | assert(RTI != MR.JD->MRTrackers.end() && "No tracker for this")(static_cast <bool> (RTI != MR.JD->MRTrackers.end() && "No tracker for this") ? void (0) : __assert_fail ("RTI != MR.JD->MRTrackers.end() && \"No tracker for this\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2700, __extension__ __PRETTY_FUNCTION__)); | |||
2701 | if (RTI->second->isDefunct()) | |||
2702 | return; | |||
2703 | ||||
2704 | std::tie(FailedQueries, FailedSymbols) = | |||
2705 | JITDylib::failSymbols(std::move(Worklist)); | |||
2706 | }); | |||
2707 | ||||
2708 | for (auto &Q : FailedQueries) | |||
2709 | Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbols)); | |||
2710 | } | |||
2711 | ||||
2712 | Error ExecutionSession::OL_replace(MaterializationResponsibility &MR, | |||
2713 | std::unique_ptr<MaterializationUnit> MU) { | |||
2714 | for (auto &KV : MU->getSymbols()) { | |||
2715 | assert(MR.SymbolFlags.count(KV.first) &&(static_cast <bool> (MR.SymbolFlags.count(KV.first) && "Replacing definition outside this responsibility set") ? void (0) : __assert_fail ("MR.SymbolFlags.count(KV.first) && \"Replacing definition outside this responsibility set\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2716, __extension__ __PRETTY_FUNCTION__)) | |||
2716 | "Replacing definition outside this responsibility set")(static_cast <bool> (MR.SymbolFlags.count(KV.first) && "Replacing definition outside this responsibility set") ? void (0) : __assert_fail ("MR.SymbolFlags.count(KV.first) && \"Replacing definition outside this responsibility set\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2716, __extension__ __PRETTY_FUNCTION__)); | |||
2717 | MR.SymbolFlags.erase(KV.first); | |||
2718 | } | |||
2719 | ||||
2720 | if (MU->getInitializerSymbol() == MR.InitSymbol) | |||
2721 | MR.InitSymbol = nullptr; | |||
2722 | ||||
2723 | LLVM_DEBUG(MR.JD->getExecutionSession().runSessionLocked([&]() {do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { MR.JD->getExecutionSession().runSessionLocked([ &]() { dbgs() << "In " << MR.JD->getName() << " replacing symbols with " << *MU << "\n" ; });; } } while (false) | |||
2724 | dbgs() << "In " << MR.JD->getName() << " replacing symbols with " << *MUdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { MR.JD->getExecutionSession().runSessionLocked([ &]() { dbgs() << "In " << MR.JD->getName() << " replacing symbols with " << *MU << "\n" ; });; } } while (false) | |||
2725 | << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { MR.JD->getExecutionSession().runSessionLocked([ &]() { dbgs() << "In " << MR.JD->getName() << " replacing symbols with " << *MU << "\n" ; });; } } while (false) | |||
2726 | });)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { MR.JD->getExecutionSession().runSessionLocked([ &]() { dbgs() << "In " << MR.JD->getName() << " replacing symbols with " << *MU << "\n" ; });; } } while (false); | |||
2727 | ||||
2728 | return MR.JD->replace(MR, std::move(MU)); | |||
2729 | } | |||
2730 | ||||
2731 | Expected<std::unique_ptr<MaterializationResponsibility>> | |||
2732 | ExecutionSession::OL_delegate(MaterializationResponsibility &MR, | |||
2733 | const SymbolNameSet &Symbols) { | |||
2734 | ||||
2735 | SymbolStringPtr DelegatedInitSymbol; | |||
2736 | SymbolFlagsMap DelegatedFlags; | |||
2737 | ||||
2738 | for (auto &Name : Symbols) { | |||
2739 | auto I = MR.SymbolFlags.find(Name); | |||
2740 | assert(I != MR.SymbolFlags.end() &&(static_cast <bool> (I != MR.SymbolFlags.end() && "Symbol is not tracked by this MaterializationResponsibility " "instance") ? void (0) : __assert_fail ("I != MR.SymbolFlags.end() && \"Symbol is not tracked by this MaterializationResponsibility \" \"instance\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2742, __extension__ __PRETTY_FUNCTION__)) | |||
2741 | "Symbol is not tracked by this MaterializationResponsibility "(static_cast <bool> (I != MR.SymbolFlags.end() && "Symbol is not tracked by this MaterializationResponsibility " "instance") ? void (0) : __assert_fail ("I != MR.SymbolFlags.end() && \"Symbol is not tracked by this MaterializationResponsibility \" \"instance\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2742, __extension__ __PRETTY_FUNCTION__)) | |||
2742 | "instance")(static_cast <bool> (I != MR.SymbolFlags.end() && "Symbol is not tracked by this MaterializationResponsibility " "instance") ? void (0) : __assert_fail ("I != MR.SymbolFlags.end() && \"Symbol is not tracked by this MaterializationResponsibility \" \"instance\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2742, __extension__ __PRETTY_FUNCTION__)); | |||
2743 | ||||
2744 | DelegatedFlags[Name] = std::move(I->second); | |||
2745 | if (Name == MR.InitSymbol) | |||
2746 | std::swap(MR.InitSymbol, DelegatedInitSymbol); | |||
2747 | ||||
2748 | MR.SymbolFlags.erase(I); | |||
2749 | } | |||
2750 | ||||
2751 | return MR.JD->delegate(MR, std::move(DelegatedFlags), | |||
2752 | std::move(DelegatedInitSymbol)); | |||
2753 | } | |||
2754 | ||||
2755 | void ExecutionSession::OL_addDependencies( | |||
2756 | MaterializationResponsibility &MR, const SymbolStringPtr &Name, | |||
2757 | const SymbolDependenceMap &Dependencies) { | |||
2758 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Adding dependencies for " << Name << ": " << Dependencies << "\n"; }; } } while (false) | |||
2759 | dbgs() << "Adding dependencies for " << Name << ": " << Dependenciesdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Adding dependencies for " << Name << ": " << Dependencies << "\n"; }; } } while (false) | |||
2760 | << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Adding dependencies for " << Name << ": " << Dependencies << "\n"; }; } } while (false) | |||
2761 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Adding dependencies for " << Name << ": " << Dependencies << "\n"; }; } } while (false); | |||
2762 | assert(MR.SymbolFlags.count(Name) &&(static_cast <bool> (MR.SymbolFlags.count(Name) && "Symbol not covered by this MaterializationResponsibility instance" ) ? void (0) : __assert_fail ("MR.SymbolFlags.count(Name) && \"Symbol not covered by this MaterializationResponsibility instance\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2763, __extension__ __PRETTY_FUNCTION__)) | |||
2763 | "Symbol not covered by this MaterializationResponsibility instance")(static_cast <bool> (MR.SymbolFlags.count(Name) && "Symbol not covered by this MaterializationResponsibility instance" ) ? void (0) : __assert_fail ("MR.SymbolFlags.count(Name) && \"Symbol not covered by this MaterializationResponsibility instance\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ExecutionEngine/Orc/Core.cpp" , 2763, __extension__ __PRETTY_FUNCTION__)); | |||
2764 | MR.JD->addDependencies(Name, Dependencies); | |||
2765 | } | |||
2766 | ||||
2767 | void ExecutionSession::OL_addDependenciesForAll( | |||
2768 | MaterializationResponsibility &MR, | |||
2769 | const SymbolDependenceMap &Dependencies) { | |||
2770 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Adding dependencies for all symbols in " << MR.SymbolFlags << ": " << Dependencies << "\n"; }; } } while (false) | |||
2771 | dbgs() << "Adding dependencies for all symbols in " << MR.SymbolFlags << ": "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Adding dependencies for all symbols in " << MR.SymbolFlags << ": " << Dependencies << "\n"; }; } } while (false) | |||
2772 | << Dependencies << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Adding dependencies for all symbols in " << MR.SymbolFlags << ": " << Dependencies << "\n"; }; } } while (false) | |||
2773 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Adding dependencies for all symbols in " << MR.SymbolFlags << ": " << Dependencies << "\n"; }; } } while (false); | |||
2774 | for (auto &KV : MR.SymbolFlags) | |||
2775 | MR.JD->addDependencies(KV.first, Dependencies); | |||
2776 | } | |||
2777 | ||||
2778 | #ifndef NDEBUG | |||
2779 | void ExecutionSession::dumpDispatchInfo(JITDylib &JD, MaterializationUnit &MU) { | |||
2780 | runSessionLocked([&]() { | |||
2781 | dbgs() << "Dispatching " << MU << " for " << JD.getName() << "\n"; | |||
2782 | }); | |||
2783 | } | |||
2784 | #endif // NDEBUG | |||
2785 | ||||
2786 | } // End namespace orc. | |||
2787 | } // End namespace llvm. |
1 | //===------ Core.h -- Core ORC APIs (Layer, JITDylib, etc.) -----*- 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 | // Contains core ORC APIs. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_EXECUTIONENGINE_ORC_CORE_H |
14 | #define LLVM_EXECUTIONENGINE_ORC_CORE_H |
15 | |
16 | #include "llvm/ADT/BitmaskEnum.h" |
17 | #include "llvm/ADT/DenseSet.h" |
18 | #include "llvm/ADT/FunctionExtras.h" |
19 | #include "llvm/ADT/IntrusiveRefCntPtr.h" |
20 | #include "llvm/ExecutionEngine/JITLink/JITLinkDylib.h" |
21 | #include "llvm/ExecutionEngine/JITSymbol.h" |
22 | #include "llvm/ExecutionEngine/Orc/SymbolStringPool.h" |
23 | #include "llvm/ExecutionEngine/OrcV1Deprecation.h" |
24 | #include "llvm/Support/Debug.h" |
25 | |
26 | #include <atomic> |
27 | #include <memory> |
28 | #include <vector> |
29 | |
30 | namespace llvm { |
31 | namespace orc { |
32 | |
33 | // Forward declare some classes. |
34 | class AsynchronousSymbolQuery; |
35 | class ExecutionSession; |
36 | class MaterializationUnit; |
37 | class MaterializationResponsibility; |
38 | class JITDylib; |
39 | class ResourceTracker; |
40 | class InProgressLookupState; |
41 | |
42 | enum class SymbolState : uint8_t; |
43 | |
44 | using ResourceTrackerSP = IntrusiveRefCntPtr<ResourceTracker>; |
45 | using JITDylibSP = IntrusiveRefCntPtr<JITDylib>; |
46 | |
47 | using ResourceKey = uintptr_t; |
48 | |
49 | /// API to remove / transfer ownership of JIT resources. |
50 | class ResourceTracker : public ThreadSafeRefCountedBase<ResourceTracker> { |
51 | private: |
52 | friend class ExecutionSession; |
53 | friend class JITDylib; |
54 | friend class MaterializationResponsibility; |
55 | |
56 | public: |
57 | ResourceTracker(const ResourceTracker &) = delete; |
58 | ResourceTracker &operator=(const ResourceTracker &) = delete; |
59 | ResourceTracker(ResourceTracker &&) = delete; |
60 | ResourceTracker &operator=(ResourceTracker &&) = delete; |
61 | |
62 | ~ResourceTracker(); |
63 | |
64 | /// Return the JITDylib targeted by this tracker. |
65 | JITDylib &getJITDylib() const { |
66 | return *reinterpret_cast<JITDylib *>(JDAndFlag.load() & |
67 | ~static_cast<uintptr_t>(1)); |
68 | } |
69 | |
70 | /// Remove all resources associated with this key. |
71 | Error remove(); |
72 | |
73 | /// Transfer all resources associated with this key to the given |
74 | /// tracker, which must target the same JITDylib as this one. |
75 | void transferTo(ResourceTracker &DstRT); |
76 | |
77 | /// Return true if this tracker has become defunct. |
78 | bool isDefunct() const { return JDAndFlag.load() & 0x1; } |
79 | |
80 | /// Returns the key associated with this tracker. |
81 | /// This method should not be used except for debug logging: there is no |
82 | /// guarantee that the returned value will remain valid. |
83 | ResourceKey getKeyUnsafe() const { return reinterpret_cast<uintptr_t>(this); } |
84 | |
85 | private: |
86 | ResourceTracker(JITDylibSP JD); |
87 | |
88 | void makeDefunct(); |
89 | |
90 | std::atomic_uintptr_t JDAndFlag; |
91 | }; |
92 | |
93 | /// Listens for ResourceTracker operations. |
94 | class ResourceManager { |
95 | public: |
96 | virtual ~ResourceManager(); |
97 | virtual Error handleRemoveResources(ResourceKey K) = 0; |
98 | virtual void handleTransferResources(ResourceKey DstK, ResourceKey SrcK) = 0; |
99 | }; |
100 | |
101 | /// A set of symbol names (represented by SymbolStringPtrs for |
102 | // efficiency). |
103 | using SymbolNameSet = DenseSet<SymbolStringPtr>; |
104 | |
105 | /// A vector of symbol names. |
106 | using SymbolNameVector = std::vector<SymbolStringPtr>; |
107 | |
108 | /// A map from symbol names (as SymbolStringPtrs) to JITSymbols |
109 | /// (address/flags pairs). |
110 | using SymbolMap = DenseMap<SymbolStringPtr, JITEvaluatedSymbol>; |
111 | |
112 | /// A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags. |
113 | using SymbolFlagsMap = DenseMap<SymbolStringPtr, JITSymbolFlags>; |
114 | |
115 | /// A map from JITDylibs to sets of symbols. |
116 | using SymbolDependenceMap = DenseMap<JITDylib *, SymbolNameSet>; |
117 | |
118 | /// Lookup flags that apply to each dylib in the search order for a lookup. |
119 | /// |
120 | /// If MatchHiddenSymbolsOnly is used (the default) for a given dylib, then |
121 | /// only symbols in that Dylib's interface will be searched. If |
122 | /// MatchHiddenSymbols is used then symbols with hidden visibility will match |
123 | /// as well. |
124 | enum class JITDylibLookupFlags { MatchExportedSymbolsOnly, MatchAllSymbols }; |
125 | |
126 | /// Lookup flags that apply to each symbol in a lookup. |
127 | /// |
128 | /// If RequiredSymbol is used (the default) for a given symbol then that symbol |
129 | /// must be found during the lookup or the lookup will fail returning a |
130 | /// SymbolNotFound error. If WeaklyReferencedSymbol is used and the given |
131 | /// symbol is not found then the query will continue, and no result for the |
132 | /// missing symbol will be present in the result (assuming the rest of the |
133 | /// lookup succeeds). |
134 | enum class SymbolLookupFlags { RequiredSymbol, WeaklyReferencedSymbol }; |
135 | |
136 | /// Describes the kind of lookup being performed. The lookup kind is passed to |
137 | /// symbol generators (if they're invoked) to help them determine what |
138 | /// definitions to generate. |
139 | /// |
140 | /// Static -- Lookup is being performed as-if at static link time (e.g. |
141 | /// generators representing static archives should pull in new |
142 | /// definitions). |
143 | /// |
144 | /// DLSym -- Lookup is being performed as-if at runtime (e.g. generators |
145 | /// representing static archives should not pull in new definitions). |
146 | enum class LookupKind { Static, DLSym }; |
147 | |
148 | /// A list of (JITDylib*, JITDylibLookupFlags) pairs to be used as a search |
149 | /// order during symbol lookup. |
150 | using JITDylibSearchOrder = |
151 | std::vector<std::pair<JITDylib *, JITDylibLookupFlags>>; |
152 | |
153 | /// Convenience function for creating a search order from an ArrayRef of |
154 | /// JITDylib*, all with the same flags. |
155 | inline JITDylibSearchOrder makeJITDylibSearchOrder( |
156 | ArrayRef<JITDylib *> JDs, |
157 | JITDylibLookupFlags Flags = JITDylibLookupFlags::MatchExportedSymbolsOnly) { |
158 | JITDylibSearchOrder O; |
159 | O.reserve(JDs.size()); |
160 | for (auto *JD : JDs) |
161 | O.push_back(std::make_pair(JD, Flags)); |
162 | return O; |
163 | } |
164 | |
165 | /// A set of symbols to look up, each associated with a SymbolLookupFlags |
166 | /// value. |
167 | /// |
168 | /// This class is backed by a vector and optimized for fast insertion, |
169 | /// deletion and iteration. It does not guarantee a stable order between |
170 | /// operations, and will not automatically detect duplicate elements (they |
171 | /// can be manually checked by calling the validate method). |
172 | class SymbolLookupSet { |
173 | public: |
174 | using value_type = std::pair<SymbolStringPtr, SymbolLookupFlags>; |
175 | using UnderlyingVector = std::vector<value_type>; |
176 | using iterator = UnderlyingVector::iterator; |
177 | using const_iterator = UnderlyingVector::const_iterator; |
178 | |
179 | SymbolLookupSet() = default; |
180 | |
181 | explicit SymbolLookupSet( |
182 | SymbolStringPtr Name, |
183 | SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) { |
184 | add(std::move(Name), Flags); |
185 | } |
186 | |
187 | /// Construct a SymbolLookupSet from an initializer list of SymbolStringPtrs. |
188 | explicit SymbolLookupSet( |
189 | std::initializer_list<SymbolStringPtr> Names, |
190 | SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) { |
191 | Symbols.reserve(Names.size()); |
192 | for (auto &Name : Names) |
193 | add(std::move(Name), Flags); |
194 | } |
195 | |
196 | /// Construct a SymbolLookupSet from a SymbolNameSet with the given |
197 | /// Flags used for each value. |
198 | explicit SymbolLookupSet( |
199 | const SymbolNameSet &Names, |
200 | SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) { |
201 | Symbols.reserve(Names.size()); |
202 | for (const auto &Name : Names) |
203 | add(Name, Flags); |
204 | } |
205 | |
206 | /// Construct a SymbolLookupSet from a vector of symbols with the given Flags |
207 | /// used for each value. |
208 | /// If the ArrayRef contains duplicates it is up to the client to remove these |
209 | /// before using this instance for lookup. |
210 | explicit SymbolLookupSet( |
211 | ArrayRef<SymbolStringPtr> Names, |
212 | SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) { |
213 | Symbols.reserve(Names.size()); |
214 | for (const auto &Name : Names) |
215 | add(Name, Flags); |
216 | } |
217 | |
218 | /// Add an element to the set. The client is responsible for checking that |
219 | /// duplicates are not added. |
220 | SymbolLookupSet & |
221 | add(SymbolStringPtr Name, |
222 | SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) { |
223 | Symbols.push_back(std::make_pair(std::move(Name), Flags)); |
224 | return *this; |
225 | } |
226 | |
227 | /// Quickly append one lookup set to another. |
228 | SymbolLookupSet &append(SymbolLookupSet Other) { |
229 | Symbols.reserve(Symbols.size() + Other.size()); |
230 | for (auto &KV : Other) |
231 | Symbols.push_back(std::move(KV)); |
232 | return *this; |
233 | } |
234 | |
235 | bool empty() const { return Symbols.empty(); } |
236 | UnderlyingVector::size_type size() const { return Symbols.size(); } |
237 | iterator begin() { return Symbols.begin(); } |
238 | iterator end() { return Symbols.end(); } |
239 | const_iterator begin() const { return Symbols.begin(); } |
240 | const_iterator end() const { return Symbols.end(); } |
241 | |
242 | /// Removes the Ith element of the vector, replacing it with the last element. |
243 | void remove(UnderlyingVector::size_type I) { |
244 | std::swap(Symbols[I], Symbols.back()); |
245 | Symbols.pop_back(); |
246 | } |
247 | |
248 | /// Removes the element pointed to by the given iterator. This iterator and |
249 | /// all subsequent ones (including end()) are invalidated. |
250 | void remove(iterator I) { remove(I - begin()); } |
251 | |
252 | /// Removes all elements matching the given predicate, which must be callable |
253 | /// as bool(const SymbolStringPtr &, SymbolLookupFlags Flags). |
254 | template <typename PredFn> void remove_if(PredFn &&Pred) { |
255 | UnderlyingVector::size_type I = 0; |
256 | while (I != Symbols.size()) { |
257 | const auto &Name = Symbols[I].first; |
258 | auto Flags = Symbols[I].second; |
259 | if (Pred(Name, Flags)) |
260 | remove(I); |
261 | else |
262 | ++I; |
263 | } |
264 | } |
265 | |
266 | /// Loop over the elements of this SymbolLookupSet, applying the Body function |
267 | /// to each one. Body must be callable as |
268 | /// bool(const SymbolStringPtr &, SymbolLookupFlags). |
269 | /// If Body returns true then the element just passed in is removed from the |
270 | /// set. If Body returns false then the element is retained. |
271 | template <typename BodyFn> |
272 | auto forEachWithRemoval(BodyFn &&Body) -> std::enable_if_t< |
273 | std::is_same<decltype(Body(std::declval<const SymbolStringPtr &>(), |
274 | std::declval<SymbolLookupFlags>())), |
275 | bool>::value> { |
276 | UnderlyingVector::size_type I = 0; |
277 | while (I != Symbols.size()) { |
278 | const auto &Name = Symbols[I].first; |
279 | auto Flags = Symbols[I].second; |
280 | if (Body(Name, Flags)) |
281 | remove(I); |
282 | else |
283 | ++I; |
284 | } |
285 | } |
286 | |
287 | /// Loop over the elements of this SymbolLookupSet, applying the Body function |
288 | /// to each one. Body must be callable as |
289 | /// Expected<bool>(const SymbolStringPtr &, SymbolLookupFlags). |
290 | /// If Body returns a failure value, the loop exits immediately. If Body |
291 | /// returns true then the element just passed in is removed from the set. If |
292 | /// Body returns false then the element is retained. |
293 | template <typename BodyFn> |
294 | auto forEachWithRemoval(BodyFn &&Body) -> std::enable_if_t< |
295 | std::is_same<decltype(Body(std::declval<const SymbolStringPtr &>(), |
296 | std::declval<SymbolLookupFlags>())), |
297 | Expected<bool>>::value, |
298 | Error> { |
299 | UnderlyingVector::size_type I = 0; |
300 | while (I != Symbols.size()) { |
301 | const auto &Name = Symbols[I].first; |
302 | auto Flags = Symbols[I].second; |
303 | auto Remove = Body(Name, Flags); |
304 | if (!Remove) |
305 | return Remove.takeError(); |
306 | if (*Remove) |
307 | remove(I); |
308 | else |
309 | ++I; |
310 | } |
311 | return Error::success(); |
312 | } |
313 | |
314 | /// Construct a SymbolNameVector from this instance by dropping the Flags |
315 | /// values. |
316 | SymbolNameVector getSymbolNames() const { |
317 | SymbolNameVector Names; |
318 | Names.reserve(Symbols.size()); |
319 | for (auto &KV : Symbols) |
320 | Names.push_back(KV.first); |
321 | return Names; |
322 | } |
323 | |
324 | /// Sort the lookup set by pointer value. This sort is fast but sensitive to |
325 | /// allocation order and so should not be used where a consistent order is |
326 | /// required. |
327 | void sortByAddress() { |
328 | llvm::sort(Symbols, [](const value_type &LHS, const value_type &RHS) { |
329 | return LHS.first < RHS.first; |
330 | }); |
331 | } |
332 | |
333 | /// Sort the lookup set lexicographically. This sort is slow but the order |
334 | /// is unaffected by allocation order. |
335 | void sortByName() { |
336 | llvm::sort(Symbols, [](const value_type &LHS, const value_type &RHS) { |
337 | return *LHS.first < *RHS.first; |
338 | }); |
339 | } |
340 | |
341 | /// Remove any duplicate elements. If a SymbolLookupSet is not duplicate-free |
342 | /// by construction, this method can be used to turn it into a proper set. |
343 | void removeDuplicates() { |
344 | sortByAddress(); |
345 | auto LastI = std::unique(Symbols.begin(), Symbols.end()); |
346 | Symbols.erase(LastI, Symbols.end()); |
347 | } |
348 | |
349 | #ifndef NDEBUG |
350 | /// Returns true if this set contains any duplicates. This should only be used |
351 | /// in assertions. |
352 | bool containsDuplicates() { |
353 | if (Symbols.size() < 2) |
354 | return false; |
355 | sortByAddress(); |
356 | for (UnderlyingVector::size_type I = 1; I != Symbols.size(); ++I) |
357 | if (Symbols[I].first == Symbols[I - 1].first) |
358 | return true; |
359 | return false; |
360 | } |
361 | #endif |
362 | |
363 | private: |
364 | UnderlyingVector Symbols; |
365 | }; |
366 | |
367 | struct SymbolAliasMapEntry { |
368 | SymbolAliasMapEntry() = default; |
369 | SymbolAliasMapEntry(SymbolStringPtr Aliasee, JITSymbolFlags AliasFlags) |
370 | : Aliasee(std::move(Aliasee)), AliasFlags(AliasFlags) {} |
371 | |
372 | SymbolStringPtr Aliasee; |
373 | JITSymbolFlags AliasFlags; |
374 | }; |
375 | |
376 | /// A map of Symbols to (Symbol, Flags) pairs. |
377 | using SymbolAliasMap = DenseMap<SymbolStringPtr, SymbolAliasMapEntry>; |
378 | |
379 | /// Callback to notify client that symbols have been resolved. |
380 | using SymbolsResolvedCallback = unique_function<void(Expected<SymbolMap>)>; |
381 | |
382 | /// Callback to register the dependencies for a given query. |
383 | using RegisterDependenciesFunction = |
384 | std::function<void(const SymbolDependenceMap &)>; |
385 | |
386 | /// This can be used as the value for a RegisterDependenciesFunction if there |
387 | /// are no dependants to register with. |
388 | extern RegisterDependenciesFunction NoDependenciesToRegister; |
389 | |
390 | class ResourceTrackerDefunct : public ErrorInfo<ResourceTrackerDefunct> { |
391 | public: |
392 | static char ID; |
393 | |
394 | ResourceTrackerDefunct(ResourceTrackerSP RT); |
395 | std::error_code convertToErrorCode() const override; |
396 | void log(raw_ostream &OS) const override; |
397 | |
398 | private: |
399 | ResourceTrackerSP RT; |
400 | }; |
401 | |
402 | /// Used to notify a JITDylib that the given set of symbols failed to |
403 | /// materialize. |
404 | class FailedToMaterialize : public ErrorInfo<FailedToMaterialize> { |
405 | public: |
406 | static char ID; |
407 | |
408 | FailedToMaterialize(std::shared_ptr<SymbolDependenceMap> Symbols); |
409 | std::error_code convertToErrorCode() const override; |
410 | void log(raw_ostream &OS) const override; |
411 | const SymbolDependenceMap &getSymbols() const { return *Symbols; } |
412 | |
413 | private: |
414 | std::shared_ptr<SymbolDependenceMap> Symbols; |
415 | }; |
416 | |
417 | /// Used to notify clients when symbols can not be found during a lookup. |
418 | class SymbolsNotFound : public ErrorInfo<SymbolsNotFound> { |
419 | public: |
420 | static char ID; |
421 | |
422 | SymbolsNotFound(SymbolNameSet Symbols); |
423 | SymbolsNotFound(SymbolNameVector Symbols); |
424 | std::error_code convertToErrorCode() const override; |
425 | void log(raw_ostream &OS) const override; |
426 | const SymbolNameVector &getSymbols() const { return Symbols; } |
427 | |
428 | private: |
429 | SymbolNameVector Symbols; |
430 | }; |
431 | |
432 | /// Used to notify clients that a set of symbols could not be removed. |
433 | class SymbolsCouldNotBeRemoved : public ErrorInfo<SymbolsCouldNotBeRemoved> { |
434 | public: |
435 | static char ID; |
436 | |
437 | SymbolsCouldNotBeRemoved(SymbolNameSet Symbols); |
438 | std::error_code convertToErrorCode() const override; |
439 | void log(raw_ostream &OS) const override; |
440 | const SymbolNameSet &getSymbols() const { return Symbols; } |
441 | |
442 | private: |
443 | SymbolNameSet Symbols; |
444 | }; |
445 | |
446 | /// Errors of this type should be returned if a module fails to include |
447 | /// definitions that are claimed by the module's associated |
448 | /// MaterializationResponsibility. If this error is returned it is indicative of |
449 | /// a broken transformation / compiler / object cache. |
450 | class MissingSymbolDefinitions : public ErrorInfo<MissingSymbolDefinitions> { |
451 | public: |
452 | static char ID; |
453 | |
454 | MissingSymbolDefinitions(std::string ModuleName, SymbolNameVector Symbols) |
455 | : ModuleName(std::move(ModuleName)), Symbols(std::move(Symbols)) {} |
456 | std::error_code convertToErrorCode() const override; |
457 | void log(raw_ostream &OS) const override; |
458 | const std::string &getModuleName() const { return ModuleName; } |
459 | const SymbolNameVector &getSymbols() const { return Symbols; } |
460 | private: |
461 | std::string ModuleName; |
462 | SymbolNameVector Symbols; |
463 | }; |
464 | |
465 | /// Errors of this type should be returned if a module contains definitions for |
466 | /// symbols that are not claimed by the module's associated |
467 | /// MaterializationResponsibility. If this error is returned it is indicative of |
468 | /// a broken transformation / compiler / object cache. |
469 | class UnexpectedSymbolDefinitions : public ErrorInfo<UnexpectedSymbolDefinitions> { |
470 | public: |
471 | static char ID; |
472 | |
473 | UnexpectedSymbolDefinitions(std::string ModuleName, SymbolNameVector Symbols) |
474 | : ModuleName(std::move(ModuleName)), Symbols(std::move(Symbols)) {} |
475 | std::error_code convertToErrorCode() const override; |
476 | void log(raw_ostream &OS) const override; |
477 | const std::string &getModuleName() const { return ModuleName; } |
478 | const SymbolNameVector &getSymbols() const { return Symbols; } |
479 | private: |
480 | std::string ModuleName; |
481 | SymbolNameVector Symbols; |
482 | }; |
483 | |
484 | /// Tracks responsibility for materialization, and mediates interactions between |
485 | /// MaterializationUnits and JDs. |
486 | /// |
487 | /// An instance of this class is passed to MaterializationUnits when their |
488 | /// materialize method is called. It allows MaterializationUnits to resolve and |
489 | /// emit symbols, or abandon materialization by notifying any unmaterialized |
490 | /// symbols of an error. |
491 | class MaterializationResponsibility { |
492 | friend class ExecutionSession; |
493 | |
494 | public: |
495 | MaterializationResponsibility(MaterializationResponsibility &&) = delete; |
496 | MaterializationResponsibility & |
497 | operator=(MaterializationResponsibility &&) = delete; |
498 | |
499 | /// Destruct a MaterializationResponsibility instance. In debug mode |
500 | /// this asserts that all symbols being tracked have been either |
501 | /// emitted or notified of an error. |
502 | ~MaterializationResponsibility(); |
503 | |
504 | /// Returns the ResourceTracker for this instance. |
505 | template <typename Func> Error withResourceKeyDo(Func &&F) const; |
506 | |
507 | /// Returns the target JITDylib that these symbols are being materialized |
508 | /// into. |
509 | JITDylib &getTargetJITDylib() const { return *JD; } |
510 | |
511 | /// Returns the ExecutionSession for this instance. |
512 | ExecutionSession &getExecutionSession(); |
513 | |
514 | /// Returns the symbol flags map for this responsibility instance. |
515 | /// Note: The returned flags may have transient flags (Lazy, Materializing) |
516 | /// set. These should be stripped with JITSymbolFlags::stripTransientFlags |
517 | /// before using. |
518 | const SymbolFlagsMap &getSymbols() const { return SymbolFlags; } |
519 | |
520 | /// Returns the initialization pseudo-symbol, if any. This symbol will also |
521 | /// be present in the SymbolFlagsMap for this MaterializationResponsibility |
522 | /// object. |
523 | const SymbolStringPtr &getInitializerSymbol() const { return InitSymbol; } |
524 | |
525 | /// Returns the names of any symbols covered by this |
526 | /// MaterializationResponsibility object that have queries pending. This |
527 | /// information can be used to return responsibility for unrequested symbols |
528 | /// back to the JITDylib via the delegate method. |
529 | SymbolNameSet getRequestedSymbols() const; |
530 | |
531 | /// Notifies the target JITDylib that the given symbols have been resolved. |
532 | /// This will update the given symbols' addresses in the JITDylib, and notify |
533 | /// any pending queries on the given symbols of their resolution. The given |
534 | /// symbols must be ones covered by this MaterializationResponsibility |
535 | /// instance. Individual calls to this method may resolve a subset of the |
536 | /// symbols, but all symbols must have been resolved prior to calling emit. |
537 | /// |
538 | /// This method will return an error if any symbols being resolved have been |
539 | /// moved to the error state due to the failure of a dependency. If this |
540 | /// method returns an error then clients should log it and call |
541 | /// failMaterialize. If no dependencies have been registered for the |
542 | /// symbols covered by this MaterializationResponsibiility then this method |
543 | /// is guaranteed to return Error::success() and can be wrapped with cantFail. |
544 | Error notifyResolved(const SymbolMap &Symbols); |
545 | |
546 | /// Notifies the target JITDylib (and any pending queries on that JITDylib) |
547 | /// that all symbols covered by this MaterializationResponsibility instance |
548 | /// have been emitted. |
549 | /// |
550 | /// This method will return an error if any symbols being resolved have been |
551 | /// moved to the error state due to the failure of a dependency. If this |
552 | /// method returns an error then clients should log it and call |
553 | /// failMaterialize. If no dependencies have been registered for the |
554 | /// symbols covered by this MaterializationResponsibiility then this method |
555 | /// is guaranteed to return Error::success() and can be wrapped with cantFail. |
556 | Error notifyEmitted(); |
557 | |
558 | /// Attempt to claim responsibility for new definitions. This method can be |
559 | /// used to claim responsibility for symbols that are added to a |
560 | /// materialization unit during the compilation process (e.g. literal pool |
561 | /// symbols). Symbol linkage rules are the same as for symbols that are |
562 | /// defined up front: duplicate strong definitions will result in errors. |
563 | /// Duplicate weak definitions will be discarded (in which case they will |
564 | /// not be added to this responsibility instance). |
565 | /// |
566 | /// This method can be used by materialization units that want to add |
567 | /// additional symbols at materialization time (e.g. stubs, compile |
568 | /// callbacks, metadata). |
569 | Error defineMaterializing(SymbolFlagsMap SymbolFlags); |
570 | |
571 | /// Define the given symbols as non-existent, removing it from the symbol |
572 | /// table and notifying any pending queries. Queries that lookup up the |
573 | /// symbol using the SymbolLookupFlags::WeaklyReferencedSymbol flag will |
574 | /// behave as if the symbol had not been matched in the first place. Queries |
575 | /// that required this symbol will fail with a missing symbol definition |
576 | /// error. |
577 | /// |
578 | /// This method is intended to support cleanup of special symbols like |
579 | /// initializer symbols: Queries using |
580 | /// SymbolLookupFlags::WeaklyReferencedSymbol can be used to trigger their |
581 | /// emission, and this method can be used to remove them from the JITDylib |
582 | /// once materialization is complete. |
583 | void defineNonExistent(ArrayRef<SymbolStringPtr> Symbols); |
584 | |
585 | /// Notify all not-yet-emitted covered by this MaterializationResponsibility |
586 | /// instance that an error has occurred. |
587 | /// This will remove all symbols covered by this MaterializationResponsibilty |
588 | /// from the target JITDylib, and send an error to any queries waiting on |
589 | /// these symbols. |
590 | void failMaterialization(); |
591 | |
592 | /// Transfers responsibility to the given MaterializationUnit for all |
593 | /// symbols defined by that MaterializationUnit. This allows |
594 | /// materializers to break up work based on run-time information (e.g. |
595 | /// by introspecting which symbols have actually been looked up and |
596 | /// materializing only those). |
597 | Error replace(std::unique_ptr<MaterializationUnit> MU); |
598 | |
599 | /// Delegates responsibility for the given symbols to the returned |
600 | /// materialization responsibility. Useful for breaking up work between |
601 | /// threads, or different kinds of materialization processes. |
602 | Expected<std::unique_ptr<MaterializationResponsibility>> |
603 | delegate(const SymbolNameSet &Symbols); |
604 | |
605 | void addDependencies(const SymbolStringPtr &Name, |
606 | const SymbolDependenceMap &Dependencies); |
607 | |
608 | /// Add dependencies that apply to all symbols covered by this instance. |
609 | void addDependenciesForAll(const SymbolDependenceMap &Dependencies); |
610 | |
611 | private: |
612 | /// Create a MaterializationResponsibility for the given JITDylib and |
613 | /// initial symbols. |
614 | MaterializationResponsibility(JITDylibSP JD, SymbolFlagsMap SymbolFlags, |
615 | SymbolStringPtr InitSymbol) |
616 | : JD(std::move(JD)), SymbolFlags(std::move(SymbolFlags)), |
617 | InitSymbol(std::move(InitSymbol)) { |
618 | assert(this->JD && "Cannot initialize with null JITDylib")(static_cast <bool> (this->JD && "Cannot initialize with null JITDylib" ) ? void (0) : __assert_fail ("this->JD && \"Cannot initialize with null JITDylib\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/include/llvm/ExecutionEngine/Orc/Core.h" , 618, __extension__ __PRETTY_FUNCTION__)); |
619 | assert(!this->SymbolFlags.empty() && "Materializing nothing?")(static_cast <bool> (!this->SymbolFlags.empty() && "Materializing nothing?") ? void (0) : __assert_fail ("!this->SymbolFlags.empty() && \"Materializing nothing?\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/include/llvm/ExecutionEngine/Orc/Core.h" , 619, __extension__ __PRETTY_FUNCTION__)); |
620 | } |
621 | |
622 | JITDylibSP JD; |
623 | SymbolFlagsMap SymbolFlags; |
624 | SymbolStringPtr InitSymbol; |
625 | }; |
626 | |
627 | /// A MaterializationUnit represents a set of symbol definitions that can |
628 | /// be materialized as a group, or individually discarded (when |
629 | /// overriding definitions are encountered). |
630 | /// |
631 | /// MaterializationUnits are used when providing lazy definitions of symbols to |
632 | /// JITDylibs. The JITDylib will call materialize when the address of a symbol |
633 | /// is requested via the lookup method. The JITDylib will call discard if a |
634 | /// stronger definition is added or already present. |
635 | class MaterializationUnit { |
636 | friend class ExecutionSession; |
637 | friend class JITDylib; |
638 | |
639 | public: |
640 | MaterializationUnit(SymbolFlagsMap InitalSymbolFlags, |
641 | SymbolStringPtr InitSymbol) |
642 | : SymbolFlags(std::move(InitalSymbolFlags)), |
643 | InitSymbol(std::move(InitSymbol)) { |
644 | assert((!this->InitSymbol || this->SymbolFlags.count(this->InitSymbol)) &&(static_cast <bool> ((!this->InitSymbol || this-> SymbolFlags.count(this->InitSymbol)) && "If set, InitSymbol should appear in InitialSymbolFlags map" ) ? void (0) : __assert_fail ("(!this->InitSymbol || this->SymbolFlags.count(this->InitSymbol)) && \"If set, InitSymbol should appear in InitialSymbolFlags map\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/include/llvm/ExecutionEngine/Orc/Core.h" , 645, __extension__ __PRETTY_FUNCTION__)) |
645 | "If set, InitSymbol should appear in InitialSymbolFlags map")(static_cast <bool> ((!this->InitSymbol || this-> SymbolFlags.count(this->InitSymbol)) && "If set, InitSymbol should appear in InitialSymbolFlags map" ) ? void (0) : __assert_fail ("(!this->InitSymbol || this->SymbolFlags.count(this->InitSymbol)) && \"If set, InitSymbol should appear in InitialSymbolFlags map\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/include/llvm/ExecutionEngine/Orc/Core.h" , 645, __extension__ __PRETTY_FUNCTION__)); |
646 | } |
647 | |
648 | virtual ~MaterializationUnit() {} |
649 | |
650 | /// Return the name of this materialization unit. Useful for debugging |
651 | /// output. |
652 | virtual StringRef getName() const = 0; |
653 | |
654 | /// Return the set of symbols that this source provides. |
655 | const SymbolFlagsMap &getSymbols() const { return SymbolFlags; } |
656 | |
657 | /// Returns the initialization symbol for this MaterializationUnit (if any). |
658 | const SymbolStringPtr &getInitializerSymbol() const { return InitSymbol; } |
659 | |
660 | /// Implementations of this method should materialize all symbols |
661 | /// in the materialzation unit, except for those that have been |
662 | /// previously discarded. |
663 | virtual void |
664 | materialize(std::unique_ptr<MaterializationResponsibility> R) = 0; |
665 | |
666 | /// Called by JITDylibs to notify MaterializationUnits that the given symbol |
667 | /// has been overridden. |
668 | void doDiscard(const JITDylib &JD, const SymbolStringPtr &Name) { |
669 | SymbolFlags.erase(Name); |
670 | discard(JD, std::move(Name)); |
671 | } |
672 | |
673 | protected: |
674 | SymbolFlagsMap SymbolFlags; |
675 | SymbolStringPtr InitSymbol; |
676 | |
677 | private: |
678 | virtual void anchor(); |
679 | |
680 | /// Implementations of this method should discard the given symbol |
681 | /// from the source (e.g. if the source is an LLVM IR Module and the |
682 | /// symbol is a function, delete the function body or mark it available |
683 | /// externally). |
684 | virtual void discard(const JITDylib &JD, const SymbolStringPtr &Name) = 0; |
685 | }; |
686 | |
687 | /// A MaterializationUnit implementation for pre-existing absolute symbols. |
688 | /// |
689 | /// All symbols will be resolved and marked ready as soon as the unit is |
690 | /// materialized. |
691 | class AbsoluteSymbolsMaterializationUnit : public MaterializationUnit { |
692 | public: |
693 | AbsoluteSymbolsMaterializationUnit(SymbolMap Symbols); |
694 | |
695 | StringRef getName() const override; |
696 | |
697 | private: |
698 | void materialize(std::unique_ptr<MaterializationResponsibility> R) override; |
699 | void discard(const JITDylib &JD, const SymbolStringPtr &Name) override; |
700 | static SymbolFlagsMap extractFlags(const SymbolMap &Symbols); |
701 | |
702 | SymbolMap Symbols; |
703 | }; |
704 | |
705 | /// Create an AbsoluteSymbolsMaterializationUnit with the given symbols. |
706 | /// Useful for inserting absolute symbols into a JITDylib. E.g.: |
707 | /// \code{.cpp} |
708 | /// JITDylib &JD = ...; |
709 | /// SymbolStringPtr Foo = ...; |
710 | /// JITEvaluatedSymbol FooSym = ...; |
711 | /// if (auto Err = JD.define(absoluteSymbols({{Foo, FooSym}}))) |
712 | /// return Err; |
713 | /// \endcode |
714 | /// |
715 | inline std::unique_ptr<AbsoluteSymbolsMaterializationUnit> |
716 | absoluteSymbols(SymbolMap Symbols) { |
717 | return std::make_unique<AbsoluteSymbolsMaterializationUnit>( |
718 | std::move(Symbols)); |
719 | } |
720 | |
721 | /// A materialization unit for symbol aliases. Allows existing symbols to be |
722 | /// aliased with alternate flags. |
723 | class ReExportsMaterializationUnit : public MaterializationUnit { |
724 | public: |
725 | /// SourceJD is allowed to be nullptr, in which case the source JITDylib is |
726 | /// taken to be whatever JITDylib these definitions are materialized in (and |
727 | /// MatchNonExported has no effect). This is useful for defining aliases |
728 | /// within a JITDylib. |
729 | /// |
730 | /// Note: Care must be taken that no sets of aliases form a cycle, as such |
731 | /// a cycle will result in a deadlock when any symbol in the cycle is |
732 | /// resolved. |
733 | ReExportsMaterializationUnit(JITDylib *SourceJD, |
734 | JITDylibLookupFlags SourceJDLookupFlags, |
735 | SymbolAliasMap Aliases); |
736 | |
737 | StringRef getName() const override; |
738 | |
739 | private: |
740 | void materialize(std::unique_ptr<MaterializationResponsibility> R) override; |
741 | void discard(const JITDylib &JD, const SymbolStringPtr &Name) override; |
742 | static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases); |
743 | |
744 | JITDylib *SourceJD = nullptr; |
745 | JITDylibLookupFlags SourceJDLookupFlags; |
746 | SymbolAliasMap Aliases; |
747 | }; |
748 | |
749 | /// Create a ReExportsMaterializationUnit with the given aliases. |
750 | /// Useful for defining symbol aliases.: E.g., given a JITDylib JD containing |
751 | /// symbols "foo" and "bar", we can define aliases "baz" (for "foo") and "qux" |
752 | /// (for "bar") with: \code{.cpp} |
753 | /// SymbolStringPtr Baz = ...; |
754 | /// SymbolStringPtr Qux = ...; |
755 | /// if (auto Err = JD.define(symbolAliases({ |
756 | /// {Baz, { Foo, JITSymbolFlags::Exported }}, |
757 | /// {Qux, { Bar, JITSymbolFlags::Weak }}})) |
758 | /// return Err; |
759 | /// \endcode |
760 | inline std::unique_ptr<ReExportsMaterializationUnit> |
761 | symbolAliases(SymbolAliasMap Aliases) { |
762 | return std::make_unique<ReExportsMaterializationUnit>( |
763 | nullptr, JITDylibLookupFlags::MatchAllSymbols, std::move(Aliases)); |
764 | } |
765 | |
766 | /// Create a materialization unit for re-exporting symbols from another JITDylib |
767 | /// with alternative names/flags. |
768 | /// SourceJD will be searched using the given JITDylibLookupFlags. |
769 | inline std::unique_ptr<ReExportsMaterializationUnit> |
770 | reexports(JITDylib &SourceJD, SymbolAliasMap Aliases, |
771 | JITDylibLookupFlags SourceJDLookupFlags = |
772 | JITDylibLookupFlags::MatchExportedSymbolsOnly) { |
773 | return std::make_unique<ReExportsMaterializationUnit>( |
774 | &SourceJD, SourceJDLookupFlags, std::move(Aliases)); |
775 | } |
776 | |
777 | /// Build a SymbolAliasMap for the common case where you want to re-export |
778 | /// symbols from another JITDylib with the same linkage/flags. |
779 | Expected<SymbolAliasMap> |
780 | buildSimpleReexportsAAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols); |
781 | |
782 | /// Represents the state that a symbol has reached during materialization. |
783 | enum class SymbolState : uint8_t { |
784 | Invalid, /// No symbol should be in this state. |
785 | NeverSearched, /// Added to the symbol table, never queried. |
786 | Materializing, /// Queried, materialization begun. |
787 | Resolved, /// Assigned address, still materializing. |
788 | Emitted, /// Emitted to memory, but waiting on transitive dependencies. |
789 | Ready = 0x3f /// Ready and safe for clients to access. |
790 | }; |
791 | |
792 | /// A symbol query that returns results via a callback when results are |
793 | /// ready. |
794 | /// |
795 | /// makes a callback when all symbols are available. |
796 | class AsynchronousSymbolQuery { |
797 | friend class ExecutionSession; |
798 | friend class InProgressFullLookupState; |
799 | friend class JITDylib; |
800 | friend class JITSymbolResolverAdapter; |
801 | friend class MaterializationResponsibility; |
802 | |
803 | public: |
804 | /// Create a query for the given symbols. The NotifyComplete |
805 | /// callback will be called once all queried symbols reach the given |
806 | /// minimum state. |
807 | AsynchronousSymbolQuery(const SymbolLookupSet &Symbols, |
808 | SymbolState RequiredState, |
809 | SymbolsResolvedCallback NotifyComplete); |
810 | |
811 | /// Notify the query that a requested symbol has reached the required state. |
812 | void notifySymbolMetRequiredState(const SymbolStringPtr &Name, |
813 | JITEvaluatedSymbol Sym); |
814 | |
815 | /// Returns true if all symbols covered by this query have been |
816 | /// resolved. |
817 | bool isComplete() const { return OutstandingSymbolsCount == 0; } |
818 | |
819 | /// Call the NotifyComplete callback. |
820 | /// |
821 | /// This should only be called if all symbols covered by the query have |
822 | /// reached the specified state. |
823 | void handleComplete(); |
824 | |
825 | private: |
826 | SymbolState getRequiredState() { return RequiredState; } |
827 | |
828 | void addQueryDependence(JITDylib &JD, SymbolStringPtr Name); |
829 | |
830 | void removeQueryDependence(JITDylib &JD, const SymbolStringPtr &Name); |
831 | |
832 | void dropSymbol(const SymbolStringPtr &Name); |
833 | |
834 | void handleFailed(Error Err); |
835 | |
836 | void detach(); |
837 | |
838 | SymbolsResolvedCallback NotifyComplete; |
839 | SymbolDependenceMap QueryRegistrations; |
840 | SymbolMap ResolvedSymbols; |
841 | size_t OutstandingSymbolsCount; |
842 | SymbolState RequiredState; |
843 | }; |
844 | |
845 | /// Wraps state for a lookup-in-progress. |
846 | /// DefinitionGenerators can optionally take ownership of a LookupState object |
847 | /// to suspend a lookup-in-progress while they search for definitions. |
848 | class LookupState { |
849 | friend class OrcV2CAPIHelper; |
850 | friend class ExecutionSession; |
851 | |
852 | public: |
853 | LookupState(); |
854 | LookupState(LookupState &&); |
855 | LookupState &operator=(LookupState &&); |
856 | ~LookupState(); |
857 | |
858 | /// Continue the lookup. This can be called by DefinitionGenerators |
859 | /// to re-start a captured query-application operation. |
860 | void continueLookup(Error Err); |
861 | |
862 | private: |
863 | LookupState(std::unique_ptr<InProgressLookupState> IPLS); |
864 | |
865 | // For C API. |
866 | void reset(InProgressLookupState *IPLS); |
867 | |
868 | std::unique_ptr<InProgressLookupState> IPLS; |
869 | }; |
870 | |
871 | /// Definition generators can be attached to JITDylibs to generate new |
872 | /// definitions for otherwise unresolved symbols during lookup. |
873 | class DefinitionGenerator { |
874 | public: |
875 | virtual ~DefinitionGenerator(); |
876 | |
877 | /// DefinitionGenerators should override this method to insert new |
878 | /// definitions into the parent JITDylib. K specifies the kind of this |
879 | /// lookup. JD specifies the target JITDylib being searched, and |
880 | /// JDLookupFlags specifies whether the search should match against |
881 | /// hidden symbols. Finally, Symbols describes the set of unresolved |
882 | /// symbols and their associated lookup flags. |
883 | virtual Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD, |
884 | JITDylibLookupFlags JDLookupFlags, |
885 | const SymbolLookupSet &LookupSet) = 0; |
886 | }; |
887 | |
888 | /// A symbol table that supports asynchoronous symbol queries. |
889 | /// |
890 | /// Represents a virtual shared object. Instances can not be copied or moved, so |
891 | /// their addresses may be used as keys for resource management. |
892 | /// JITDylib state changes must be made via an ExecutionSession to guarantee |
893 | /// that they are synchronized with respect to other JITDylib operations. |
894 | class JITDylib : public ThreadSafeRefCountedBase<JITDylib>, |
895 | public jitlink::JITLinkDylib { |
896 | friend class AsynchronousSymbolQuery; |
897 | friend class ExecutionSession; |
898 | friend class Platform; |
899 | friend class MaterializationResponsibility; |
900 | public: |
901 | |
902 | using AsynchronousSymbolQuerySet = |
903 | std::set<std::shared_ptr<AsynchronousSymbolQuery>>; |
904 | |
905 | JITDylib(const JITDylib &) = delete; |
906 | JITDylib &operator=(const JITDylib &) = delete; |
907 | JITDylib(JITDylib &&) = delete; |
908 | JITDylib &operator=(JITDylib &&) = delete; |
909 | |
910 | /// Get the name for this JITDylib. |
911 | const std::string &getName() const { return JITDylibName; } |
912 | |
913 | /// Get a reference to the ExecutionSession for this JITDylib. |
914 | ExecutionSession &getExecutionSession() const { return ES; } |
915 | |
916 | /// Calls remove on all trackers currently associated with this JITDylib. |
917 | /// Does not run static deinits. |
918 | /// |
919 | /// Note that removal happens outside the session lock, so new code may be |
920 | /// added concurrently while the clear is underway, and the newly added |
921 | /// code will *not* be cleared. Adding new code concurrently with a clear |
922 | /// is usually a bug and should be avoided. |
923 | Error clear(); |
924 | |
925 | /// Get the default resource tracker for this JITDylib. |
926 | ResourceTrackerSP getDefaultResourceTracker(); |
927 | |
928 | /// Create a resource tracker for this JITDylib. |
929 | ResourceTrackerSP createResourceTracker(); |
930 | |
931 | /// Adds a definition generator to this JITDylib and returns a referenece to |
932 | /// it. |
933 | /// |
934 | /// When JITDylibs are searched during lookup, if no existing definition of |
935 | /// a symbol is found, then any generators that have been added are run (in |
936 | /// the order that they were added) to potentially generate a definition. |
937 | template <typename GeneratorT> |
938 | GeneratorT &addGenerator(std::unique_ptr<GeneratorT> DefGenerator); |
939 | |
940 | /// Remove a definition generator from this JITDylib. |
941 | /// |
942 | /// The given generator must exist in this JITDylib's generators list (i.e. |
943 | /// have been added and not yet removed). |
944 | void removeGenerator(DefinitionGenerator &G); |
945 | |
946 | /// Set the link order to be used when fixing up definitions in JITDylib. |
947 | /// This will replace the previous link order, and apply to any symbol |
948 | /// resolutions made for definitions in this JITDylib after the call to |
949 | /// setLinkOrder (even if the definition itself was added before the |
950 | /// call). |
951 | /// |
952 | /// If LinkAgainstThisJITDylibFirst is true (the default) then this JITDylib |
953 | /// will add itself to the beginning of the LinkOrder (Clients should not |
954 | /// put this JITDylib in the list in this case, to avoid redundant lookups). |
955 | /// |
956 | /// If LinkAgainstThisJITDylibFirst is false then the link order will be used |
957 | /// as-is. The primary motivation for this feature is to support deliberate |
958 | /// shadowing of symbols in this JITDylib by a facade JITDylib. For example, |
959 | /// the facade may resolve function names to stubs, and the stubs may compile |
960 | /// lazily by looking up symbols in this dylib. Adding the facade dylib |
961 | /// as the first in the link order (instead of this dylib) ensures that |
962 | /// definitions within this dylib resolve to the lazy-compiling stubs, |
963 | /// rather than immediately materializing the definitions in this dylib. |
964 | void setLinkOrder(JITDylibSearchOrder NewSearchOrder, |
965 | bool LinkAgainstThisJITDylibFirst = true); |
966 | |
967 | /// Add the given JITDylib to the link order for definitions in this |
968 | /// JITDylib. |
969 | void addToLinkOrder(JITDylib &JD, |
970 | JITDylibLookupFlags JDLookupFlags = |
971 | JITDylibLookupFlags::MatchExportedSymbolsOnly); |
972 | |
973 | /// Replace OldJD with NewJD in the link order if OldJD is present. |
974 | /// Otherwise this operation is a no-op. |
975 | void replaceInLinkOrder(JITDylib &OldJD, JITDylib &NewJD, |
976 | JITDylibLookupFlags JDLookupFlags = |
977 | JITDylibLookupFlags::MatchExportedSymbolsOnly); |
978 | |
979 | /// Remove the given JITDylib from the link order for this JITDylib if it is |
980 | /// present. Otherwise this operation is a no-op. |
981 | void removeFromLinkOrder(JITDylib &JD); |
982 | |
983 | /// Do something with the link order (run under the session lock). |
984 | template <typename Func> |
985 | auto withLinkOrderDo(Func &&F) |
986 | -> decltype(F(std::declval<const JITDylibSearchOrder &>())); |
987 | |
988 | /// Define all symbols provided by the materialization unit to be part of this |
989 | /// JITDylib. |
990 | /// |
991 | /// If RT is not specified then the default resource tracker will be used. |
992 | /// |
993 | /// This overload always takes ownership of the MaterializationUnit. If any |
994 | /// errors occur, the MaterializationUnit consumed. |
995 | template <typename MaterializationUnitType> |
996 | Error define(std::unique_ptr<MaterializationUnitType> &&MU, |
997 | ResourceTrackerSP RT = nullptr); |
998 | |
999 | /// Define all symbols provided by the materialization unit to be part of this |
1000 | /// JITDylib. |
1001 | /// |
1002 | /// This overload only takes ownership of the MaterializationUnit no error is |
1003 | /// generated. If an error occurs, ownership remains with the caller. This |
1004 | /// may allow the caller to modify the MaterializationUnit to correct the |
1005 | /// issue, then re-call define. |
1006 | template <typename MaterializationUnitType> |
1007 | Error define(std::unique_ptr<MaterializationUnitType> &MU, |
1008 | ResourceTrackerSP RT = nullptr); |
1009 | |
1010 | /// Tries to remove the given symbols. |
1011 | /// |
1012 | /// If any symbols are not defined in this JITDylib this method will return |
1013 | /// a SymbolsNotFound error covering the missing symbols. |
1014 | /// |
1015 | /// If all symbols are found but some symbols are in the process of being |
1016 | /// materialized this method will return a SymbolsCouldNotBeRemoved error. |
1017 | /// |
1018 | /// On success, all symbols are removed. On failure, the JITDylib state is |
1019 | /// left unmodified (no symbols are removed). |
1020 | Error remove(const SymbolNameSet &Names); |
1021 | |
1022 | /// Dump current JITDylib state to OS. |
1023 | void dump(raw_ostream &OS); |
1024 | |
1025 | /// Returns the given JITDylibs and all of their transitive dependencies in |
1026 | /// DFS order (based on linkage relationships). Each JITDylib will appear |
1027 | /// only once. |
1028 | static std::vector<JITDylibSP> getDFSLinkOrder(ArrayRef<JITDylibSP> JDs); |
1029 | |
1030 | /// Returns the given JITDylibs and all of their transitive dependensies in |
1031 | /// reverse DFS order (based on linkage relationships). Each JITDylib will |
1032 | /// appear only once. |
1033 | static std::vector<JITDylibSP> |
1034 | getReverseDFSLinkOrder(ArrayRef<JITDylibSP> JDs); |
1035 | |
1036 | /// Return this JITDylib and its transitive dependencies in DFS order |
1037 | /// based on linkage relationships. |
1038 | std::vector<JITDylibSP> getDFSLinkOrder(); |
1039 | |
1040 | /// Rteurn this JITDylib and its transitive dependencies in reverse DFS order |
1041 | /// based on linkage relationships. |
1042 | std::vector<JITDylibSP> getReverseDFSLinkOrder(); |
1043 | |
1044 | private: |
1045 | using AsynchronousSymbolQueryList = |
1046 | std::vector<std::shared_ptr<AsynchronousSymbolQuery>>; |
1047 | |
1048 | struct UnmaterializedInfo { |
1049 | UnmaterializedInfo(std::unique_ptr<MaterializationUnit> MU, |
1050 | ResourceTracker *RT) |
1051 | : MU(std::move(MU)), RT(RT) {} |
1052 | |
1053 | std::unique_ptr<MaterializationUnit> MU; |
1054 | ResourceTracker *RT; |
1055 | }; |
1056 | |
1057 | using UnmaterializedInfosMap = |
1058 | DenseMap<SymbolStringPtr, std::shared_ptr<UnmaterializedInfo>>; |
1059 | |
1060 | using UnmaterializedInfosList = |
1061 | std::vector<std::shared_ptr<UnmaterializedInfo>>; |
1062 | |
1063 | struct MaterializingInfo { |
1064 | SymbolDependenceMap Dependants; |
1065 | SymbolDependenceMap UnemittedDependencies; |
1066 | |
1067 | void addQuery(std::shared_ptr<AsynchronousSymbolQuery> Q); |
1068 | void removeQuery(const AsynchronousSymbolQuery &Q); |
1069 | AsynchronousSymbolQueryList takeQueriesMeeting(SymbolState RequiredState); |
1070 | AsynchronousSymbolQueryList takeAllPendingQueries() { |
1071 | return std::move(PendingQueries); |
1072 | } |
1073 | bool hasQueriesPending() const { return !PendingQueries.empty(); } |
1074 | const AsynchronousSymbolQueryList &pendingQueries() const { |
1075 | return PendingQueries; |
1076 | } |
1077 | private: |
1078 | AsynchronousSymbolQueryList PendingQueries; |
1079 | }; |
1080 | |
1081 | using MaterializingInfosMap = DenseMap<SymbolStringPtr, MaterializingInfo>; |
1082 | |
1083 | class SymbolTableEntry { |
1084 | public: |
1085 | SymbolTableEntry() = default; |
1086 | SymbolTableEntry(JITSymbolFlags Flags) |
1087 | : Flags(Flags), State(static_cast<uint8_t>(SymbolState::NeverSearched)), |
1088 | MaterializerAttached(false), PendingRemoval(false) {} |
1089 | |
1090 | JITTargetAddress getAddress() const { return Addr; } |
1091 | JITSymbolFlags getFlags() const { return Flags; } |
1092 | SymbolState getState() const { return static_cast<SymbolState>(State); } |
1093 | |
1094 | bool hasMaterializerAttached() const { return MaterializerAttached; } |
1095 | bool isPendingRemoval() const { return PendingRemoval; } |
1096 | |
1097 | void setAddress(JITTargetAddress Addr) { this->Addr = Addr; } |
1098 | void setFlags(JITSymbolFlags Flags) { this->Flags = Flags; } |
1099 | void setState(SymbolState State) { |
1100 | assert(static_cast<uint8_t>(State) < (1 << 6) &&(static_cast <bool> (static_cast<uint8_t>(State) < (1 << 6) && "State does not fit in bitfield") ? void (0) : __assert_fail ("static_cast<uint8_t>(State) < (1 << 6) && \"State does not fit in bitfield\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/include/llvm/ExecutionEngine/Orc/Core.h" , 1101, __extension__ __PRETTY_FUNCTION__)) |
1101 | "State does not fit in bitfield")(static_cast <bool> (static_cast<uint8_t>(State) < (1 << 6) && "State does not fit in bitfield") ? void (0) : __assert_fail ("static_cast<uint8_t>(State) < (1 << 6) && \"State does not fit in bitfield\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/include/llvm/ExecutionEngine/Orc/Core.h" , 1101, __extension__ __PRETTY_FUNCTION__)); |
1102 | this->State = static_cast<uint8_t>(State); |
1103 | } |
1104 | |
1105 | void setMaterializerAttached(bool MaterializerAttached) { |
1106 | this->MaterializerAttached = MaterializerAttached; |
1107 | } |
1108 | |
1109 | void setPendingRemoval(bool PendingRemoval) { |
1110 | this->PendingRemoval = PendingRemoval; |
1111 | } |
1112 | |
1113 | JITEvaluatedSymbol getSymbol() const { |
1114 | return JITEvaluatedSymbol(Addr, Flags); |
1115 | } |
1116 | |
1117 | private: |
1118 | JITTargetAddress Addr = 0; |
1119 | JITSymbolFlags Flags; |
1120 | uint8_t State : 6; |
1121 | uint8_t MaterializerAttached : 1; |
1122 | uint8_t PendingRemoval : 1; |
1123 | }; |
1124 | |
1125 | using SymbolTable = DenseMap<SymbolStringPtr, SymbolTableEntry>; |
1126 | |
1127 | JITDylib(ExecutionSession &ES, std::string Name); |
1128 | |
1129 | ResourceTrackerSP getTracker(MaterializationResponsibility &MR); |
1130 | std::pair<AsynchronousSymbolQuerySet, std::shared_ptr<SymbolDependenceMap>> |
1131 | removeTracker(ResourceTracker &RT); |
1132 | |
1133 | void transferTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT); |
1134 | |
1135 | Error defineImpl(MaterializationUnit &MU); |
1136 | |
1137 | void installMaterializationUnit(std::unique_ptr<MaterializationUnit> MU, |
1138 | ResourceTracker &RT); |
1139 | |
1140 | void detachQueryHelper(AsynchronousSymbolQuery &Q, |
1141 | const SymbolNameSet &QuerySymbols); |
1142 | |
1143 | void transferEmittedNodeDependencies(MaterializingInfo &DependantMI, |
1144 | const SymbolStringPtr &DependantName, |
1145 | MaterializingInfo &EmittedMI); |
1146 | |
1147 | Expected<SymbolFlagsMap> defineMaterializing(SymbolFlagsMap SymbolFlags); |
1148 | |
1149 | Error replace(MaterializationResponsibility &FromMR, |
1150 | std::unique_ptr<MaterializationUnit> MU); |
1151 | |
1152 | Expected<std::unique_ptr<MaterializationResponsibility>> |
1153 | delegate(MaterializationResponsibility &FromMR, SymbolFlagsMap SymbolFlags, |
1154 | SymbolStringPtr InitSymbol); |
1155 | |
1156 | SymbolNameSet getRequestedSymbols(const SymbolFlagsMap &SymbolFlags) const; |
1157 | |
1158 | void addDependencies(const SymbolStringPtr &Name, |
1159 | const SymbolDependenceMap &Dependants); |
1160 | |
1161 | Error resolve(MaterializationResponsibility &MR, const SymbolMap &Resolved); |
1162 | |
1163 | Error emit(MaterializationResponsibility &MR, const SymbolFlagsMap &Emitted); |
1164 | |
1165 | void unlinkMaterializationResponsibility(MaterializationResponsibility &MR); |
1166 | |
1167 | using FailedSymbolsWorklist = |
1168 | std::vector<std::pair<JITDylib *, SymbolStringPtr>>; |
1169 | |
1170 | static std::pair<AsynchronousSymbolQuerySet, |
1171 | std::shared_ptr<SymbolDependenceMap>> |
1172 | failSymbols(FailedSymbolsWorklist); |
1173 | |
1174 | ExecutionSession &ES; |
1175 | std::string JITDylibName; |
1176 | std::mutex GeneratorsMutex; |
1177 | bool Open = true; |
1178 | SymbolTable Symbols; |
1179 | UnmaterializedInfosMap UnmaterializedInfos; |
1180 | MaterializingInfosMap MaterializingInfos; |
1181 | std::vector<std::shared_ptr<DefinitionGenerator>> DefGenerators; |
1182 | JITDylibSearchOrder LinkOrder; |
1183 | ResourceTrackerSP DefaultTracker; |
1184 | |
1185 | // Map trackers to sets of symbols tracked. |
1186 | DenseMap<ResourceTracker *, SymbolNameVector> TrackerSymbols; |
1187 | DenseMap<MaterializationResponsibility *, ResourceTracker *> MRTrackers; |
1188 | }; |
1189 | |
1190 | /// Platforms set up standard symbols and mediate interactions between dynamic |
1191 | /// initializers (e.g. C++ static constructors) and ExecutionSession state. |
1192 | /// Note that Platforms do not automatically run initializers: clients are still |
1193 | /// responsible for doing this. |
1194 | class Platform { |
1195 | public: |
1196 | virtual ~Platform(); |
1197 | |
1198 | /// This method will be called outside the session lock each time a JITDylib |
1199 | /// is created (unless it is created with EmptyJITDylib set) to allow the |
1200 | /// Platform to install any JITDylib specific standard symbols (e.g |
1201 | /// __dso_handle). |
1202 | virtual Error setupJITDylib(JITDylib &JD) = 0; |
1203 | |
1204 | /// This method will be called under the ExecutionSession lock each time a |
1205 | /// MaterializationUnit is added to a JITDylib. |
1206 | virtual Error notifyAdding(ResourceTracker &RT, |
1207 | const MaterializationUnit &MU) = 0; |
1208 | |
1209 | /// This method will be called under the ExecutionSession lock when a |
1210 | /// ResourceTracker is removed. |
1211 | virtual Error notifyRemoving(ResourceTracker &RT) = 0; |
1212 | |
1213 | /// A utility function for looking up initializer symbols. Performs a blocking |
1214 | /// lookup for the given symbols in each of the given JITDylibs. |
1215 | static Expected<DenseMap<JITDylib *, SymbolMap>> |
1216 | lookupInitSymbols(ExecutionSession &ES, |
1217 | const DenseMap<JITDylib *, SymbolLookupSet> &InitSyms); |
1218 | }; |
1219 | |
1220 | /// An ExecutionSession represents a running JIT program. |
1221 | class ExecutionSession { |
1222 | friend class InProgressLookupFlagsState; |
1223 | friend class InProgressFullLookupState; |
1224 | friend class JITDylib; |
1225 | friend class LookupState; |
1226 | friend class MaterializationResponsibility; |
1227 | friend class ResourceTracker; |
1228 | |
1229 | public: |
1230 | /// For reporting errors. |
1231 | using ErrorReporter = std::function<void(Error)>; |
1232 | |
1233 | /// For dispatching MaterializationUnit::materialize calls. |
1234 | using DispatchMaterializationFunction = |
1235 | std::function<void(std::unique_ptr<MaterializationUnit> MU, |
1236 | std::unique_ptr<MaterializationResponsibility> MR)>; |
1237 | |
1238 | /// Construct an ExecutionSession. |
1239 | /// |
1240 | /// SymbolStringPools may be shared between ExecutionSessions. |
1241 | ExecutionSession(std::shared_ptr<SymbolStringPool> SSP = nullptr); |
1242 | |
1243 | /// End the session. Closes all JITDylibs. |
1244 | Error endSession(); |
1245 | |
1246 | /// Add a symbol name to the SymbolStringPool and return a pointer to it. |
1247 | SymbolStringPtr intern(StringRef SymName) { return SSP->intern(SymName); } |
1248 | |
1249 | /// Returns a shared_ptr to the SymbolStringPool for this ExecutionSession. |
1250 | std::shared_ptr<SymbolStringPool> getSymbolStringPool() const { return SSP; } |
1251 | |
1252 | /// Set the Platform for this ExecutionSession. |
1253 | void setPlatform(std::unique_ptr<Platform> P) { this->P = std::move(P); } |
1254 | |
1255 | /// Get the Platform for this session. |
1256 | /// Will return null if no Platform has been set for this ExecutionSession. |
1257 | Platform *getPlatform() { return P.get(); } |
1258 | |
1259 | /// Run the given lambda with the session mutex locked. |
1260 | template <typename Func> decltype(auto) runSessionLocked(Func &&F) { |
1261 | std::lock_guard<std::recursive_mutex> Lock(SessionMutex); |
1262 | return F(); |
1263 | } |
1264 | |
1265 | /// Register the given ResourceManager with this ExecutionSession. |
1266 | /// Managers will be notified of events in reverse order of registration. |
1267 | void registerResourceManager(ResourceManager &RM); |
1268 | |
1269 | /// Deregister the given ResourceManager with this ExecutionSession. |
1270 | /// Manager must have been previously registered. |
1271 | void deregisterResourceManager(ResourceManager &RM); |
1272 | |
1273 | /// Return a pointer to the "name" JITDylib. |
1274 | /// Ownership of JITDylib remains within Execution Session |
1275 | JITDylib *getJITDylibByName(StringRef Name); |
1276 | |
1277 | /// Add a new bare JITDylib to this ExecutionSession. |
1278 | /// |
1279 | /// The JITDylib Name is required to be unique. Clients should verify that |
1280 | /// names are not being re-used (E.g. by calling getJITDylibByName) if names |
1281 | /// are based on user input. |
1282 | /// |
1283 | /// This call does not install any library code or symbols into the newly |
1284 | /// created JITDylib. The client is responsible for all configuration. |
1285 | JITDylib &createBareJITDylib(std::string Name); |
1286 | |
1287 | /// Add a new JITDylib to this ExecutionSession. |
1288 | /// |
1289 | /// The JITDylib Name is required to be unique. Clients should verify that |
1290 | /// names are not being re-used (e.g. by calling getJITDylibByName) if names |
1291 | /// are based on user input. |
1292 | /// |
1293 | /// If a Platform is attached then Platform::setupJITDylib will be called to |
1294 | /// install standard platform symbols (e.g. standard library interposes). |
1295 | /// If no Platform is attached this call is equivalent to createBareJITDylib. |
1296 | Expected<JITDylib &> createJITDylib(std::string Name); |
1297 | |
1298 | /// Set the error reporter function. |
1299 | ExecutionSession &setErrorReporter(ErrorReporter ReportError) { |
1300 | this->ReportError = std::move(ReportError); |
1301 | return *this; |
1302 | } |
1303 | |
1304 | /// Report a error for this execution session. |
1305 | /// |
1306 | /// Unhandled errors can be sent here to log them. |
1307 | void reportError(Error Err) { ReportError(std::move(Err)); } |
1308 | |
1309 | /// Set the materialization dispatch function. |
1310 | ExecutionSession &setDispatchMaterialization( |
1311 | DispatchMaterializationFunction DispatchMaterialization) { |
1312 | this->DispatchMaterialization = std::move(DispatchMaterialization); |
1313 | return *this; |
1314 | } |
1315 | |
1316 | /// Search the given JITDylibs to find the flags associated with each of the |
1317 | /// given symbols. |
1318 | void lookupFlags(LookupKind K, JITDylibSearchOrder SearchOrder, |
1319 | SymbolLookupSet Symbols, |
1320 | unique_function<void(Expected<SymbolFlagsMap>)> OnComplete); |
1321 | |
1322 | /// Blocking version of lookupFlags. |
1323 | Expected<SymbolFlagsMap> lookupFlags(LookupKind K, |
1324 | JITDylibSearchOrder SearchOrder, |
1325 | SymbolLookupSet Symbols); |
1326 | |
1327 | /// Search the given JITDylibs for the given symbols. |
1328 | /// |
1329 | /// SearchOrder lists the JITDylibs to search. For each dylib, the associated |
1330 | /// boolean indicates whether the search should match against non-exported |
1331 | /// (hidden visibility) symbols in that dylib (true means match against |
1332 | /// non-exported symbols, false means do not match). |
1333 | /// |
1334 | /// The NotifyComplete callback will be called once all requested symbols |
1335 | /// reach the required state. |
1336 | /// |
1337 | /// If all symbols are found, the RegisterDependencies function will be called |
1338 | /// while the session lock is held. This gives clients a chance to register |
1339 | /// dependencies for on the queried symbols for any symbols they are |
1340 | /// materializing (if a MaterializationResponsibility instance is present, |
1341 | /// this can be implemented by calling |
1342 | /// MaterializationResponsibility::addDependencies). If there are no |
1343 | /// dependenant symbols for this query (e.g. it is being made by a top level |
1344 | /// client to get an address to call) then the value NoDependenciesToRegister |
1345 | /// can be used. |
1346 | void lookup(LookupKind K, const JITDylibSearchOrder &SearchOrder, |
1347 | SymbolLookupSet Symbols, SymbolState RequiredState, |
1348 | SymbolsResolvedCallback NotifyComplete, |
1349 | RegisterDependenciesFunction RegisterDependencies); |
1350 | |
1351 | /// Blocking version of lookup above. Returns the resolved symbol map. |
1352 | /// If WaitUntilReady is true (the default), will not return until all |
1353 | /// requested symbols are ready (or an error occurs). If WaitUntilReady is |
1354 | /// false, will return as soon as all requested symbols are resolved, |
1355 | /// or an error occurs. If WaitUntilReady is false and an error occurs |
1356 | /// after resolution, the function will return a success value, but the |
1357 | /// error will be reported via reportErrors. |
1358 | Expected<SymbolMap> lookup(const JITDylibSearchOrder &SearchOrder, |
1359 | const SymbolLookupSet &Symbols, |
1360 | LookupKind K = LookupKind::Static, |
1361 | SymbolState RequiredState = SymbolState::Ready, |
1362 | RegisterDependenciesFunction RegisterDependencies = |
1363 | NoDependenciesToRegister); |
1364 | |
1365 | /// Convenience version of blocking lookup. |
1366 | /// Searches each of the JITDylibs in the search order in turn for the given |
1367 | /// symbol. |
1368 | Expected<JITEvaluatedSymbol> |
1369 | lookup(const JITDylibSearchOrder &SearchOrder, SymbolStringPtr Symbol, |
1370 | SymbolState RequiredState = SymbolState::Ready); |
1371 | |
1372 | /// Convenience version of blocking lookup. |
1373 | /// Searches each of the JITDylibs in the search order in turn for the given |
1374 | /// symbol. The search will not find non-exported symbols. |
1375 | Expected<JITEvaluatedSymbol> |
1376 | lookup(ArrayRef<JITDylib *> SearchOrder, SymbolStringPtr Symbol, |
1377 | SymbolState RequiredState = SymbolState::Ready); |
1378 | |
1379 | /// Convenience version of blocking lookup. |
1380 | /// Searches each of the JITDylibs in the search order in turn for the given |
1381 | /// symbol. The search will not find non-exported symbols. |
1382 | Expected<JITEvaluatedSymbol> |
1383 | lookup(ArrayRef<JITDylib *> SearchOrder, StringRef Symbol, |
1384 | SymbolState RequiredState = SymbolState::Ready); |
1385 | |
1386 | /// Materialize the given unit. |
1387 | void |
1388 | dispatchMaterialization(std::unique_ptr<MaterializationUnit> MU, |
1389 | std::unique_ptr<MaterializationResponsibility> MR) { |
1390 | assert(MU && "MU must be non-null")(static_cast <bool> (MU && "MU must be non-null" ) ? void (0) : __assert_fail ("MU && \"MU must be non-null\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/include/llvm/ExecutionEngine/Orc/Core.h" , 1390, __extension__ __PRETTY_FUNCTION__)); |
1391 | DEBUG_WITH_TYPE("orc", dumpDispatchInfo(MR->getTargetJITDylib(), *MU))do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { dumpDispatchInfo(MR->getTargetJITDylib(), *MU); } } while (false); |
1392 | DispatchMaterialization(std::move(MU), std::move(MR)); |
1393 | } |
1394 | |
1395 | /// Dump the state of all the JITDylibs in this session. |
1396 | void dump(raw_ostream &OS); |
1397 | |
1398 | private: |
1399 | static void logErrorsToStdErr(Error Err) { |
1400 | logAllUnhandledErrors(std::move(Err), errs(), "JIT session error: "); |
1401 | } |
1402 | |
1403 | static void materializeOnCurrentThread( |
1404 | std::unique_ptr<MaterializationUnit> MU, |
1405 | std::unique_ptr<MaterializationResponsibility> MR) { |
1406 | MU->materialize(std::move(MR)); |
1407 | } |
1408 | |
1409 | void dispatchOutstandingMUs(); |
1410 | |
1411 | static std::unique_ptr<MaterializationResponsibility> |
1412 | createMaterializationResponsibility(ResourceTracker &RT, |
1413 | SymbolFlagsMap Symbols, |
1414 | SymbolStringPtr InitSymbol) { |
1415 | auto &JD = RT.getJITDylib(); |
1416 | std::unique_ptr<MaterializationResponsibility> MR( |
1417 | new MaterializationResponsibility(&JD, std::move(Symbols), |
1418 | std::move(InitSymbol))); |
1419 | JD.MRTrackers[MR.get()] = &RT; |
1420 | return MR; |
1421 | } |
1422 | |
1423 | Error removeResourceTracker(ResourceTracker &RT); |
1424 | void transferResourceTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT); |
1425 | void destroyResourceTracker(ResourceTracker &RT); |
1426 | |
1427 | // State machine functions for query application.. |
1428 | |
1429 | /// IL_updateCandidatesFor is called to remove already-defined symbols that |
1430 | /// match a given query from the set of candidate symbols to generate |
1431 | /// definitions for (no need to generate a definition if one already exists). |
1432 | Error IL_updateCandidatesFor(JITDylib &JD, JITDylibLookupFlags JDLookupFlags, |
1433 | SymbolLookupSet &Candidates, |
1434 | SymbolLookupSet *NonCandidates); |
1435 | |
1436 | /// OL_applyQueryPhase1 is an optionally re-startable loop for triggering |
1437 | /// definition generation. It is called when a lookup is performed, and again |
1438 | /// each time that LookupState::continueLookup is called. |
1439 | void OL_applyQueryPhase1(std::unique_ptr<InProgressLookupState> IPLS, |
1440 | Error Err); |
1441 | |
1442 | /// OL_completeLookup is run once phase 1 successfully completes for a lookup |
1443 | /// call. It attempts to attach the symbol to all symbol table entries and |
1444 | /// collect all MaterializationUnits to dispatch. If this method fails then |
1445 | /// all MaterializationUnits will be left un-materialized. |
1446 | void OL_completeLookup(std::unique_ptr<InProgressLookupState> IPLS, |
1447 | std::shared_ptr<AsynchronousSymbolQuery> Q, |
1448 | RegisterDependenciesFunction RegisterDependencies); |
1449 | |
1450 | /// OL_completeLookupFlags is run once phase 1 successfully completes for a |
1451 | /// lookupFlags call. |
1452 | void OL_completeLookupFlags( |
1453 | std::unique_ptr<InProgressLookupState> IPLS, |
1454 | unique_function<void(Expected<SymbolFlagsMap>)> OnComplete); |
1455 | |
1456 | // State machine functions for MaterializationResponsibility. |
1457 | void OL_destroyMaterializationResponsibility( |
1458 | MaterializationResponsibility &MR); |
1459 | SymbolNameSet OL_getRequestedSymbols(const MaterializationResponsibility &MR); |
1460 | Error OL_notifyResolved(MaterializationResponsibility &MR, |
1461 | const SymbolMap &Symbols); |
1462 | Error OL_notifyEmitted(MaterializationResponsibility &MR); |
1463 | Error OL_defineMaterializing(MaterializationResponsibility &MR, |
1464 | SymbolFlagsMap SymbolFlags); |
1465 | void OL_notifyFailed(MaterializationResponsibility &MR); |
1466 | Error OL_replace(MaterializationResponsibility &MR, |
1467 | std::unique_ptr<MaterializationUnit> MU); |
1468 | Expected<std::unique_ptr<MaterializationResponsibility>> |
1469 | OL_delegate(MaterializationResponsibility &MR, const SymbolNameSet &Symbols); |
1470 | void OL_addDependencies(MaterializationResponsibility &MR, |
1471 | const SymbolStringPtr &Name, |
1472 | const SymbolDependenceMap &Dependencies); |
1473 | void OL_addDependenciesForAll(MaterializationResponsibility &MR, |
1474 | const SymbolDependenceMap &Dependencies); |
1475 | |
1476 | #ifndef NDEBUG |
1477 | void dumpDispatchInfo(JITDylib &JD, MaterializationUnit &MU); |
1478 | #endif // NDEBUG |
1479 | |
1480 | mutable std::recursive_mutex SessionMutex; |
1481 | bool SessionOpen = true; |
1482 | std::shared_ptr<SymbolStringPool> SSP; |
1483 | std::unique_ptr<Platform> P; |
1484 | ErrorReporter ReportError = logErrorsToStdErr; |
1485 | DispatchMaterializationFunction DispatchMaterialization = |
1486 | materializeOnCurrentThread; |
1487 | |
1488 | std::vector<ResourceManager *> ResourceManagers; |
1489 | |
1490 | std::vector<JITDylibSP> JDs; |
1491 | |
1492 | // FIXME: Remove this (and runOutstandingMUs) once the linking layer works |
1493 | // with callbacks from asynchronous queries. |
1494 | mutable std::recursive_mutex OutstandingMUsMutex; |
1495 | std::vector<std::pair<std::unique_ptr<MaterializationUnit>, |
1496 | std::unique_ptr<MaterializationResponsibility>>> |
1497 | OutstandingMUs; |
1498 | }; |
1499 | |
1500 | inline ExecutionSession &MaterializationResponsibility::getExecutionSession() { |
1501 | return JD->getExecutionSession(); |
1502 | } |
1503 | |
1504 | template <typename Func> |
1505 | Error MaterializationResponsibility::withResourceKeyDo(Func &&F) const { |
1506 | return JD->getExecutionSession().runSessionLocked([&]() -> Error { |
1507 | auto I = JD->MRTrackers.find(this); |
1508 | assert(I != JD->MRTrackers.end() && "No tracker for this MR")(static_cast <bool> (I != JD->MRTrackers.end() && "No tracker for this MR") ? void (0) : __assert_fail ("I != JD->MRTrackers.end() && \"No tracker for this MR\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/include/llvm/ExecutionEngine/Orc/Core.h" , 1508, __extension__ __PRETTY_FUNCTION__)); |
1509 | if (I->second->isDefunct()) |
1510 | return make_error<ResourceTrackerDefunct>(I->second); |
1511 | F(I->second->getKeyUnsafe()); |
1512 | return Error::success(); |
1513 | }); |
1514 | } |
1515 | |
1516 | template <typename GeneratorT> |
1517 | GeneratorT &JITDylib::addGenerator(std::unique_ptr<GeneratorT> DefGenerator) { |
1518 | auto &G = *DefGenerator; |
1519 | std::lock_guard<std::mutex> Lock(GeneratorsMutex); |
1520 | DefGenerators.push_back(std::move(DefGenerator)); |
1521 | return G; |
1522 | } |
1523 | |
1524 | template <typename Func> |
1525 | auto JITDylib::withLinkOrderDo(Func &&F) |
1526 | -> decltype(F(std::declval<const JITDylibSearchOrder &>())) { |
1527 | return ES.runSessionLocked([&]() { return F(LinkOrder); }); |
1528 | } |
1529 | |
1530 | template <typename MaterializationUnitType> |
1531 | Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &&MU, |
1532 | ResourceTrackerSP RT) { |
1533 | assert(MU && "Can not define with a null MU")(static_cast <bool> (MU && "Can not define with a null MU" ) ? void (0) : __assert_fail ("MU && \"Can not define with a null MU\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/include/llvm/ExecutionEngine/Orc/Core.h" , 1533, __extension__ __PRETTY_FUNCTION__)); |
1534 | |
1535 | if (MU->getSymbols().empty()) { |
1536 | // Empty MUs are allowable but pathological, so issue a warning. |
1537 | DEBUG_WITH_TYPE("orc", {do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Warning: Discarding empty MU " << MU->getName() << " for " << getName() << "\n"; }; } } while (false) |
1538 | dbgs() << "Warning: Discarding empty MU " << MU->getName() << " for "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Warning: Discarding empty MU " << MU->getName() << " for " << getName() << "\n"; }; } } while (false) |
1539 | << getName() << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Warning: Discarding empty MU " << MU->getName() << " for " << getName() << "\n"; }; } } while (false) |
1540 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Warning: Discarding empty MU " << MU->getName() << " for " << getName() << "\n"; }; } } while (false); |
1541 | return Error::success(); |
1542 | } else |
1543 | DEBUG_WITH_TYPE("orc", {do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Defining MU " << MU->getName () << " for " << getName() << " (tracker: " ; if (RT == getDefaultResourceTracker()) dbgs() << "default)" ; else if (RT) dbgs() << RT.get() << ")\n"; else dbgs () << "0x0, default will be used)\n"; }; } } while (false ) |
1544 | dbgs() << "Defining MU " << MU->getName() << " for " << getName()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Defining MU " << MU->getName () << " for " << getName() << " (tracker: " ; if (RT == getDefaultResourceTracker()) dbgs() << "default)" ; else if (RT) dbgs() << RT.get() << ")\n"; else dbgs () << "0x0, default will be used)\n"; }; } } while (false ) |
1545 | << " (tracker: ";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Defining MU " << MU->getName () << " for " << getName() << " (tracker: " ; if (RT == getDefaultResourceTracker()) dbgs() << "default)" ; else if (RT) dbgs() << RT.get() << ")\n"; else dbgs () << "0x0, default will be used)\n"; }; } } while (false ) |
1546 | if (RT == getDefaultResourceTracker())do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Defining MU " << MU->getName () << " for " << getName() << " (tracker: " ; if (RT == getDefaultResourceTracker()) dbgs() << "default)" ; else if (RT) dbgs() << RT.get() << ")\n"; else dbgs () << "0x0, default will be used)\n"; }; } } while (false ) |
1547 | dbgs() << "default)";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Defining MU " << MU->getName () << " for " << getName() << " (tracker: " ; if (RT == getDefaultResourceTracker()) dbgs() << "default)" ; else if (RT) dbgs() << RT.get() << ")\n"; else dbgs () << "0x0, default will be used)\n"; }; } } while (false ) |
1548 | else if (RT)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Defining MU " << MU->getName () << " for " << getName() << " (tracker: " ; if (RT == getDefaultResourceTracker()) dbgs() << "default)" ; else if (RT) dbgs() << RT.get() << ")\n"; else dbgs () << "0x0, default will be used)\n"; }; } } while (false ) |
1549 | dbgs() << RT.get() << ")\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Defining MU " << MU->getName () << " for " << getName() << " (tracker: " ; if (RT == getDefaultResourceTracker()) dbgs() << "default)" ; else if (RT) dbgs() << RT.get() << ")\n"; else dbgs () << "0x0, default will be used)\n"; }; } } while (false ) |
1550 | elsedo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Defining MU " << MU->getName () << " for " << getName() << " (tracker: " ; if (RT == getDefaultResourceTracker()) dbgs() << "default)" ; else if (RT) dbgs() << RT.get() << ")\n"; else dbgs () << "0x0, default will be used)\n"; }; } } while (false ) |
1551 | dbgs() << "0x0, default will be used)\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Defining MU " << MU->getName () << " for " << getName() << " (tracker: " ; if (RT == getDefaultResourceTracker()) dbgs() << "default)" ; else if (RT) dbgs() << RT.get() << ")\n"; else dbgs () << "0x0, default will be used)\n"; }; } } while (false ) |
1552 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Defining MU " << MU->getName () << " for " << getName() << " (tracker: " ; if (RT == getDefaultResourceTracker()) dbgs() << "default)" ; else if (RT) dbgs() << RT.get() << ")\n"; else dbgs () << "0x0, default will be used)\n"; }; } } while (false ); |
1553 | |
1554 | return ES.runSessionLocked([&, this]() -> Error { |
1555 | if (auto Err = defineImpl(*MU)) |
1556 | return Err; |
1557 | |
1558 | if (!RT) |
1559 | RT = getDefaultResourceTracker(); |
1560 | |
1561 | if (auto *P = ES.getPlatform()) { |
1562 | if (auto Err = P->notifyAdding(*RT, *MU)) |
1563 | return Err; |
1564 | } |
1565 | |
1566 | installMaterializationUnit(std::move(MU), *RT); |
1567 | return Error::success(); |
1568 | }); |
1569 | } |
1570 | |
1571 | template <typename MaterializationUnitType> |
1572 | Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &MU, |
1573 | ResourceTrackerSP RT) { |
1574 | assert(MU && "Can not define with a null MU")(static_cast <bool> (MU && "Can not define with a null MU" ) ? void (0) : __assert_fail ("MU && \"Can not define with a null MU\"" , "/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/include/llvm/ExecutionEngine/Orc/Core.h" , 1574, __extension__ __PRETTY_FUNCTION__)); |
1575 | |
1576 | if (MU->getSymbols().empty()) { |
1577 | // Empty MUs are allowable but pathological, so issue a warning. |
1578 | DEBUG_WITH_TYPE("orc", {do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Warning: Discarding empty MU " << MU->getName() << getName() << "\n"; }; } } while (false) |
1579 | dbgs() << "Warning: Discarding empty MU " << MU->getName() << getName()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Warning: Discarding empty MU " << MU->getName() << getName() << "\n"; }; } } while (false) |
1580 | << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Warning: Discarding empty MU " << MU->getName() << getName() << "\n"; }; } } while (false) |
1581 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Warning: Discarding empty MU " << MU->getName() << getName() << "\n"; }; } } while (false); |
1582 | return Error::success(); |
1583 | } else |
1584 | DEBUG_WITH_TYPE("orc", {do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Defining MU " << MU->getName () << " for " << getName() << " (tracker: " ; if (RT == getDefaultResourceTracker()) dbgs() << "default)" ; else if (RT) dbgs() << RT.get() << ")\n"; else dbgs () << "0x0, default will be used)\n"; }; } } while (false ) |
1585 | dbgs() << "Defining MU " << MU->getName() << " for " << getName()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Defining MU " << MU->getName () << " for " << getName() << " (tracker: " ; if (RT == getDefaultResourceTracker()) dbgs() << "default)" ; else if (RT) dbgs() << RT.get() << ")\n"; else dbgs () << "0x0, default will be used)\n"; }; } } while (false ) |
1586 | << " (tracker: ";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Defining MU " << MU->getName () << " for " << getName() << " (tracker: " ; if (RT == getDefaultResourceTracker()) dbgs() << "default)" ; else if (RT) dbgs() << RT.get() << ")\n"; else dbgs () << "0x0, default will be used)\n"; }; } } while (false ) |
1587 | if (RT == getDefaultResourceTracker())do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Defining MU " << MU->getName () << " for " << getName() << " (tracker: " ; if (RT == getDefaultResourceTracker()) dbgs() << "default)" ; else if (RT) dbgs() << RT.get() << ")\n"; else dbgs () << "0x0, default will be used)\n"; }; } } while (false ) |
1588 | dbgs() << "default)";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Defining MU " << MU->getName () << " for " << getName() << " (tracker: " ; if (RT == getDefaultResourceTracker()) dbgs() << "default)" ; else if (RT) dbgs() << RT.get() << ")\n"; else dbgs () << "0x0, default will be used)\n"; }; } } while (false ) |
1589 | else if (RT)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Defining MU " << MU->getName () << " for " << getName() << " (tracker: " ; if (RT == getDefaultResourceTracker()) dbgs() << "default)" ; else if (RT) dbgs() << RT.get() << ")\n"; else dbgs () << "0x0, default will be used)\n"; }; } } while (false ) |
1590 | dbgs() << RT.get() << ")\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Defining MU " << MU->getName () << " for " << getName() << " (tracker: " ; if (RT == getDefaultResourceTracker()) dbgs() << "default)" ; else if (RT) dbgs() << RT.get() << ")\n"; else dbgs () << "0x0, default will be used)\n"; }; } } while (false ) |
1591 | elsedo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Defining MU " << MU->getName () << " for " << getName() << " (tracker: " ; if (RT == getDefaultResourceTracker()) dbgs() << "default)" ; else if (RT) dbgs() << RT.get() << ")\n"; else dbgs () << "0x0, default will be used)\n"; }; } } while (false ) |
1592 | dbgs() << "0x0, default will be used)\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Defining MU " << MU->getName () << " for " << getName() << " (tracker: " ; if (RT == getDefaultResourceTracker()) dbgs() << "default)" ; else if (RT) dbgs() << RT.get() << ")\n"; else dbgs () << "0x0, default will be used)\n"; }; } } while (false ) |
1593 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("orc")) { { dbgs() << "Defining MU " << MU->getName () << " for " << getName() << " (tracker: " ; if (RT == getDefaultResourceTracker()) dbgs() << "default)" ; else if (RT) dbgs() << RT.get() << ")\n"; else dbgs () << "0x0, default will be used)\n"; }; } } while (false ); |
1594 | |
1595 | return ES.runSessionLocked([&, this]() -> Error { |
1596 | if (auto Err = defineImpl(*MU)) |
1597 | return Err; |
1598 | |
1599 | if (!RT) |
1600 | RT = getDefaultResourceTracker(); |
1601 | |
1602 | if (auto *P = ES.getPlatform()) { |
1603 | if (auto Err = P->notifyAdding(*RT, *MU)) |
1604 | return Err; |
1605 | } |
1606 | |
1607 | installMaterializationUnit(std::move(MU), *RT); |
1608 | return Error::success(); |
1609 | }); |
1610 | } |
1611 | |
1612 | /// ReexportsGenerator can be used with JITDylib::addGenerator to automatically |
1613 | /// re-export a subset of the source JITDylib's symbols in the target. |
1614 | class ReexportsGenerator : public DefinitionGenerator { |
1615 | public: |
1616 | using SymbolPredicate = std::function<bool(SymbolStringPtr)>; |
1617 | |
1618 | /// Create a reexports generator. If an Allow predicate is passed, only |
1619 | /// symbols for which the predicate returns true will be reexported. If no |
1620 | /// Allow predicate is passed, all symbols will be exported. |
1621 | ReexportsGenerator(JITDylib &SourceJD, |
1622 | JITDylibLookupFlags SourceJDLookupFlags, |
1623 | SymbolPredicate Allow = SymbolPredicate()); |
1624 | |
1625 | Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD, |
1626 | JITDylibLookupFlags JDLookupFlags, |
1627 | const SymbolLookupSet &LookupSet) override; |
1628 | |
1629 | private: |
1630 | JITDylib &SourceJD; |
1631 | JITDylibLookupFlags SourceJDLookupFlags; |
1632 | SymbolPredicate Allow; |
1633 | }; |
1634 | |
1635 | // --------------- IMPLEMENTATION -------------- |
1636 | // Implementations for inline functions/methods. |
1637 | // --------------------------------------------- |
1638 | |
1639 | inline MaterializationResponsibility::~MaterializationResponsibility() { |
1640 | JD->getExecutionSession().OL_destroyMaterializationResponsibility(*this); |
1641 | } |
1642 | |
1643 | inline SymbolNameSet MaterializationResponsibility::getRequestedSymbols() const { |
1644 | return JD->getExecutionSession().OL_getRequestedSymbols(*this); |
1645 | } |
1646 | |
1647 | inline Error MaterializationResponsibility::notifyResolved( |
1648 | const SymbolMap &Symbols) { |
1649 | return JD->getExecutionSession().OL_notifyResolved(*this, Symbols); |
1650 | } |
1651 | |
1652 | inline Error MaterializationResponsibility::notifyEmitted() { |
1653 | return JD->getExecutionSession().OL_notifyEmitted(*this); |
1654 | } |
1655 | |
1656 | inline Error MaterializationResponsibility::defineMaterializing( |
1657 | SymbolFlagsMap SymbolFlags) { |
1658 | return JD->getExecutionSession().OL_defineMaterializing( |
1659 | *this, std::move(SymbolFlags)); |
1660 | } |
1661 | |
1662 | inline void MaterializationResponsibility::failMaterialization() { |
1663 | JD->getExecutionSession().OL_notifyFailed(*this); |
1664 | } |
1665 | |
1666 | inline Error MaterializationResponsibility::replace( |
1667 | std::unique_ptr<MaterializationUnit> MU) { |
1668 | return JD->getExecutionSession().OL_replace(*this, std::move(MU)); |
1669 | } |
1670 | |
1671 | inline Expected<std::unique_ptr<MaterializationResponsibility>> |
1672 | MaterializationResponsibility::delegate(const SymbolNameSet &Symbols) { |
1673 | return JD->getExecutionSession().OL_delegate(*this, Symbols); |
1674 | } |
1675 | |
1676 | inline void MaterializationResponsibility::addDependencies( |
1677 | const SymbolStringPtr &Name, const SymbolDependenceMap &Dependencies) { |
1678 | JD->getExecutionSession().OL_addDependencies(*this, Name, Dependencies); |
1679 | } |
1680 | |
1681 | inline void MaterializationResponsibility::addDependenciesForAll( |
1682 | const SymbolDependenceMap &Dependencies) { |
1683 | JD->getExecutionSession().OL_addDependenciesForAll(*this, Dependencies); |
1684 | } |
1685 | |
1686 | } // End namespace orc |
1687 | } // End namespace llvm |
1688 | |
1689 | #endif // LLVM_EXECUTIONENGINE_ORC_CORE_H |
1 | //===- FunctionExtras.h - Function type erasure utilities -------*- 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 | /// \file | |||
9 | /// This file provides a collection of function (or more generally, callable) | |||
10 | /// type erasure utilities supplementing those provided by the standard library | |||
11 | /// in `<function>`. | |||
12 | /// | |||
13 | /// It provides `unique_function`, which works like `std::function` but supports | |||
14 | /// move-only callable objects and const-qualification. | |||
15 | /// | |||
16 | /// Future plans: | |||
17 | /// - Add a `function` that provides ref-qualified support, which doesn't work | |||
18 | /// with `std::function`. | |||
19 | /// - Provide support for specifying multiple signatures to type erase callable | |||
20 | /// objects with an overload set, such as those produced by generic lambdas. | |||
21 | /// - Expand to include a copyable utility that directly replaces std::function | |||
22 | /// but brings the above improvements. | |||
23 | /// | |||
24 | /// Note that LLVM's utilities are greatly simplified by not supporting | |||
25 | /// allocators. | |||
26 | /// | |||
27 | /// If the standard library ever begins to provide comparable facilities we can | |||
28 | /// consider switching to those. | |||
29 | /// | |||
30 | //===----------------------------------------------------------------------===// | |||
31 | ||||
32 | #ifndef LLVM_ADT_FUNCTIONEXTRAS_H | |||
33 | #define LLVM_ADT_FUNCTIONEXTRAS_H | |||
34 | ||||
35 | #include "llvm/ADT/PointerIntPair.h" | |||
36 | #include "llvm/ADT/PointerUnion.h" | |||
37 | #include "llvm/ADT/STLForwardCompat.h" | |||
38 | #include "llvm/Support/MemAlloc.h" | |||
39 | #include "llvm/Support/type_traits.h" | |||
40 | #include <memory> | |||
41 | #include <type_traits> | |||
42 | ||||
43 | namespace llvm { | |||
44 | ||||
45 | /// unique_function is a type-erasing functor similar to std::function. | |||
46 | /// | |||
47 | /// It can hold move-only function objects, like lambdas capturing unique_ptrs. | |||
48 | /// Accordingly, it is movable but not copyable. | |||
49 | /// | |||
50 | /// It supports const-qualification: | |||
51 | /// - unique_function<int() const> has a const operator(). | |||
52 | /// It can only hold functions which themselves have a const operator(). | |||
53 | /// - unique_function<int()> has a non-const operator(). | |||
54 | /// It can hold functions with a non-const operator(), like mutable lambdas. | |||
55 | template <typename FunctionT> class unique_function; | |||
56 | ||||
57 | namespace detail { | |||
58 | ||||
59 | template <typename T> | |||
60 | using EnableIfTrivial = | |||
61 | std::enable_if_t<llvm::is_trivially_move_constructible<T>::value && | |||
62 | std::is_trivially_destructible<T>::value>; | |||
63 | template <typename CallableT, typename ThisT> | |||
64 | using EnableUnlessSameType = | |||
65 | std::enable_if_t<!std::is_same<remove_cvref_t<CallableT>, ThisT>::value>; | |||
66 | template <typename CallableT, typename Ret, typename... Params> | |||
67 | using EnableIfCallable = | |||
68 | std::enable_if_t<std::is_void<Ret>::value || | |||
69 | std::is_convertible<decltype(std::declval<CallableT>()( | |||
70 | std::declval<Params>()...)), | |||
71 | Ret>::value>; | |||
72 | ||||
73 | template <typename ReturnT, typename... ParamTs> class UniqueFunctionBase { | |||
74 | protected: | |||
75 | static constexpr size_t InlineStorageSize = sizeof(void *) * 3; | |||
76 | ||||
77 | template <typename T, class = void> | |||
78 | struct IsSizeLessThanThresholdT : std::false_type {}; | |||
79 | ||||
80 | template <typename T> | |||
81 | struct IsSizeLessThanThresholdT< | |||
82 | T, std::enable_if_t<sizeof(T) <= 2 * sizeof(void *)>> : std::true_type {}; | |||
83 | ||||
84 | // Provide a type function to map parameters that won't observe extra copies | |||
85 | // or moves and which are small enough to likely pass in register to values | |||
86 | // and all other types to l-value reference types. We use this to compute the | |||
87 | // types used in our erased call utility to minimize copies and moves unless | |||
88 | // doing so would force things unnecessarily into memory. | |||
89 | // | |||
90 | // The heuristic used is related to common ABI register passing conventions. | |||
91 | // It doesn't have to be exact though, and in one way it is more strict | |||
92 | // because we want to still be able to observe either moves *or* copies. | |||
93 | template <typename T> | |||
94 | using AdjustedParamT = typename std::conditional< | |||
95 | !std::is_reference<T>::value && | |||
96 | llvm::is_trivially_copy_constructible<T>::value && | |||
97 | llvm::is_trivially_move_constructible<T>::value && | |||
98 | IsSizeLessThanThresholdT<T>::value, | |||
99 | T, T &>::type; | |||
100 | ||||
101 | // The type of the erased function pointer we use as a callback to dispatch to | |||
102 | // the stored callable when it is trivial to move and destroy. | |||
103 | using CallPtrT = ReturnT (*)(void *CallableAddr, | |||
104 | AdjustedParamT<ParamTs>... Params); | |||
105 | using MovePtrT = void (*)(void *LHSCallableAddr, void *RHSCallableAddr); | |||
106 | using DestroyPtrT = void (*)(void *CallableAddr); | |||
107 | ||||
108 | /// A struct to hold a single trivial callback with sufficient alignment for | |||
109 | /// our bitpacking. | |||
110 | struct alignas(8) TrivialCallback { | |||
111 | CallPtrT CallPtr; | |||
112 | }; | |||
113 | ||||
114 | /// A struct we use to aggregate three callbacks when we need full set of | |||
115 | /// operations. | |||
116 | struct alignas(8) NonTrivialCallbacks { | |||
117 | CallPtrT CallPtr; | |||
118 | MovePtrT MovePtr; | |||
119 | DestroyPtrT DestroyPtr; | |||
120 | }; | |||
121 | ||||
122 | // Create a pointer union between either a pointer to a static trivial call | |||
123 | // pointer in a struct or a pointer to a static struct of the call, move, and | |||
124 | // destroy pointers. | |||
125 | using CallbackPointerUnionT = | |||
126 | PointerUnion<TrivialCallback *, NonTrivialCallbacks *>; | |||
127 | ||||
128 | // The main storage buffer. This will either have a pointer to out-of-line | |||
129 | // storage or an inline buffer storing the callable. | |||
130 | union StorageUnionT { | |||
131 | // For out-of-line storage we keep a pointer to the underlying storage and | |||
132 | // the size. This is enough to deallocate the memory. | |||
133 | struct OutOfLineStorageT { | |||
134 | void *StoragePtr; | |||
135 | size_t Size; | |||
136 | size_t Alignment; | |||
137 | } OutOfLineStorage; | |||
138 | static_assert( | |||
139 | sizeof(OutOfLineStorageT) <= InlineStorageSize, | |||
140 | "Should always use all of the out-of-line storage for inline storage!"); | |||
141 | ||||
142 | // For in-line storage, we just provide an aligned character buffer. We | |||
143 | // provide three pointers worth of storage here. | |||
144 | // This is mutable as an inlined `const unique_function<void() const>` may | |||
145 | // still modify its own mutable members. | |||
146 | mutable | |||
147 | typename std::aligned_storage<InlineStorageSize, alignof(void *)>::type | |||
148 | InlineStorage; | |||
149 | } StorageUnion; | |||
150 | ||||
151 | // A compressed pointer to either our dispatching callback or our table of | |||
152 | // dispatching callbacks and the flag for whether the callable itself is | |||
153 | // stored inline or not. | |||
154 | PointerIntPair<CallbackPointerUnionT, 1, bool> CallbackAndInlineFlag; | |||
155 | ||||
156 | bool isInlineStorage() const { return CallbackAndInlineFlag.getInt(); } | |||
157 | ||||
158 | bool isTrivialCallback() const { | |||
159 | return CallbackAndInlineFlag.getPointer().template is<TrivialCallback *>(); | |||
160 | } | |||
161 | ||||
162 | CallPtrT getTrivialCallback() const { | |||
163 | return CallbackAndInlineFlag.getPointer().template get<TrivialCallback *>()->CallPtr; | |||
164 | } | |||
165 | ||||
166 | NonTrivialCallbacks *getNonTrivialCallbacks() const { | |||
167 | return CallbackAndInlineFlag.getPointer() | |||
168 | .template get<NonTrivialCallbacks *>(); | |||
169 | } | |||
170 | ||||
171 | CallPtrT getCallPtr() const { | |||
172 | return isTrivialCallback() ? getTrivialCallback() | |||
173 | : getNonTrivialCallbacks()->CallPtr; | |||
174 | } | |||
175 | ||||
176 | // These three functions are only const in the narrow sense. They return | |||
177 | // mutable pointers to function state. | |||
178 | // This allows unique_function<T const>::operator() to be const, even if the | |||
179 | // underlying functor may be internally mutable. | |||
180 | // | |||
181 | // const callers must ensure they're only used in const-correct ways. | |||
182 | void *getCalleePtr() const { | |||
183 | return isInlineStorage() ? getInlineStorage() : getOutOfLineStorage(); | |||
184 | } | |||
185 | void *getInlineStorage() const { return &StorageUnion.InlineStorage; } | |||
186 | void *getOutOfLineStorage() const { | |||
187 | return StorageUnion.OutOfLineStorage.StoragePtr; | |||
| ||||
188 | } | |||
189 | ||||
190 | size_t getOutOfLineStorageSize() const { | |||
191 | return StorageUnion.OutOfLineStorage.Size; | |||
192 | } | |||
193 | size_t getOutOfLineStorageAlignment() const { | |||
194 | return StorageUnion.OutOfLineStorage.Alignment; | |||
195 | } | |||
196 | ||||
197 | void setOutOfLineStorage(void *Ptr, size_t Size, size_t Alignment) { | |||
198 | StorageUnion.OutOfLineStorage = {Ptr, Size, Alignment}; | |||
199 | } | |||
200 | ||||
201 | template <typename CalledAsT> | |||
202 | static ReturnT CallImpl(void *CallableAddr, | |||
203 | AdjustedParamT<ParamTs>... Params) { | |||
204 | auto &Func = *reinterpret_cast<CalledAsT *>(CallableAddr); | |||
205 | return Func(std::forward<ParamTs>(Params)...); | |||
206 | } | |||
207 | ||||
208 | template <typename CallableT> | |||
209 | static void MoveImpl(void *LHSCallableAddr, void *RHSCallableAddr) noexcept { | |||
210 | new (LHSCallableAddr) | |||
211 | CallableT(std::move(*reinterpret_cast<CallableT *>(RHSCallableAddr))); | |||
212 | } | |||
213 | ||||
214 | template <typename CallableT> | |||
215 | static void DestroyImpl(void *CallableAddr) noexcept { | |||
216 | reinterpret_cast<CallableT *>(CallableAddr)->~CallableT(); | |||
217 | } | |||
218 | ||||
219 | // The pointers to call/move/destroy functions are determined for each | |||
220 | // callable type (and called-as type, which determines the overload chosen). | |||
221 | // (definitions are out-of-line). | |||
222 | ||||
223 | // By default, we need an object that contains all the different | |||
224 | // type erased behaviors needed. Create a static instance of the struct type | |||
225 | // here and each instance will contain a pointer to it. | |||
226 | // Wrap in a struct to avoid https://gcc.gnu.org/PR71954 | |||
227 | template <typename CallableT, typename CalledAs, typename Enable = void> | |||
228 | struct CallbacksHolder { | |||
229 | static NonTrivialCallbacks Callbacks; | |||
230 | }; | |||
231 | // See if we can create a trivial callback. We need the callable to be | |||
232 | // trivially moved and trivially destroyed so that we don't have to store | |||
233 | // type erased callbacks for those operations. | |||
234 | template <typename CallableT, typename CalledAs> | |||
235 | struct CallbacksHolder<CallableT, CalledAs, EnableIfTrivial<CallableT>> { | |||
236 | static TrivialCallback Callbacks; | |||
237 | }; | |||
238 | ||||
239 | // A simple tag type so the call-as type to be passed to the constructor. | |||
240 | template <typename T> struct CalledAs {}; | |||
241 | ||||
242 | // Essentially the "main" unique_function constructor, but subclasses | |||
243 | // provide the qualified type to be used for the call. | |||
244 | // (We always store a T, even if the call will use a pointer to const T). | |||
245 | template <typename CallableT, typename CalledAsT> | |||
246 | UniqueFunctionBase(CallableT Callable, CalledAs<CalledAsT>) { | |||
247 | bool IsInlineStorage = true; | |||
248 | void *CallableAddr = getInlineStorage(); | |||
249 | if (sizeof(CallableT) > InlineStorageSize || | |||
250 | alignof(CallableT) > alignof(decltype(StorageUnion.InlineStorage))) { | |||
251 | IsInlineStorage = false; | |||
252 | // Allocate out-of-line storage. FIXME: Use an explicit alignment | |||
253 | // parameter in C++17 mode. | |||
254 | auto Size = sizeof(CallableT); | |||
255 | auto Alignment = alignof(CallableT); | |||
256 | CallableAddr = allocate_buffer(Size, Alignment); | |||
257 | setOutOfLineStorage(CallableAddr, Size, Alignment); | |||
258 | } | |||
259 | ||||
260 | // Now move into the storage. | |||
261 | new (CallableAddr) CallableT(std::move(Callable)); | |||
262 | CallbackAndInlineFlag.setPointerAndInt( | |||
263 | &CallbacksHolder<CallableT, CalledAsT>::Callbacks, IsInlineStorage); | |||
264 | } | |||
265 | ||||
266 | ~UniqueFunctionBase() { | |||
267 | if (!CallbackAndInlineFlag.getPointer()) | |||
268 | return; | |||
269 | ||||
270 | // Cache this value so we don't re-check it after type-erased operations. | |||
271 | bool IsInlineStorage = isInlineStorage(); | |||
272 | ||||
273 | if (!isTrivialCallback()) | |||
274 | getNonTrivialCallbacks()->DestroyPtr( | |||
275 | IsInlineStorage ? getInlineStorage() : getOutOfLineStorage()); | |||
276 | ||||
277 | if (!IsInlineStorage) | |||
278 | deallocate_buffer(getOutOfLineStorage(), getOutOfLineStorageSize(), | |||
279 | getOutOfLineStorageAlignment()); | |||
280 | } | |||
281 | ||||
282 | UniqueFunctionBase(UniqueFunctionBase &&RHS) noexcept { | |||
283 | // Copy the callback and inline flag. | |||
284 | CallbackAndInlineFlag = RHS.CallbackAndInlineFlag; | |||
285 | ||||
286 | // If the RHS is empty, just copying the above is sufficient. | |||
287 | if (!RHS) | |||
288 | return; | |||
289 | ||||
290 | if (!isInlineStorage()) { | |||
291 | // The out-of-line case is easiest to move. | |||
292 | StorageUnion.OutOfLineStorage = RHS.StorageUnion.OutOfLineStorage; | |||
293 | } else if (isTrivialCallback()) { | |||
294 | // Move is trivial, just memcpy the bytes across. | |||
295 | memcpy(getInlineStorage(), RHS.getInlineStorage(), InlineStorageSize); | |||
296 | } else { | |||
297 | // Non-trivial move, so dispatch to a type-erased implementation. | |||
298 | getNonTrivialCallbacks()->MovePtr(getInlineStorage(), | |||
299 | RHS.getInlineStorage()); | |||
300 | } | |||
301 | ||||
302 | // Clear the old callback and inline flag to get back to as-if-null. | |||
303 | RHS.CallbackAndInlineFlag = {}; | |||
304 | ||||
305 | #ifndef NDEBUG | |||
306 | // In debug builds, we also scribble across the rest of the storage. | |||
307 | memset(RHS.getInlineStorage(), 0xAD, InlineStorageSize); | |||
308 | #endif | |||
309 | } | |||
310 | ||||
311 | UniqueFunctionBase &operator=(UniqueFunctionBase &&RHS) noexcept { | |||
312 | if (this == &RHS) | |||
313 | return *this; | |||
314 | ||||
315 | // Because we don't try to provide any exception safety guarantees we can | |||
316 | // implement move assignment very simply by first destroying the current | |||
317 | // object and then move-constructing over top of it. | |||
318 | this->~UniqueFunctionBase(); | |||
319 | new (this) UniqueFunctionBase(std::move(RHS)); | |||
320 | return *this; | |||
321 | } | |||
322 | ||||
323 | UniqueFunctionBase() = default; | |||
324 | ||||
325 | public: | |||
326 | explicit operator bool() const { | |||
327 | return (bool)CallbackAndInlineFlag.getPointer(); | |||
328 | } | |||
329 | }; | |||
330 | ||||
331 | template <typename R, typename... P> | |||
332 | template <typename CallableT, typename CalledAsT, typename Enable> | |||
333 | typename UniqueFunctionBase<R, P...>::NonTrivialCallbacks UniqueFunctionBase< | |||
334 | R, P...>::CallbacksHolder<CallableT, CalledAsT, Enable>::Callbacks = { | |||
335 | &CallImpl<CalledAsT>, &MoveImpl<CallableT>, &DestroyImpl<CallableT>}; | |||
336 | ||||
337 | template <typename R, typename... P> | |||
338 | template <typename CallableT, typename CalledAsT> | |||
339 | typename UniqueFunctionBase<R, P...>::TrivialCallback | |||
340 | UniqueFunctionBase<R, P...>::CallbacksHolder< | |||
341 | CallableT, CalledAsT, EnableIfTrivial<CallableT>>::Callbacks{ | |||
342 | &CallImpl<CalledAsT>}; | |||
343 | ||||
344 | } // namespace detail | |||
345 | ||||
346 | template <typename R, typename... P> | |||
347 | class unique_function<R(P...)> : public detail::UniqueFunctionBase<R, P...> { | |||
348 | using Base = detail::UniqueFunctionBase<R, P...>; | |||
349 | ||||
350 | public: | |||
351 | unique_function() = default; | |||
352 | unique_function(std::nullptr_t) {} | |||
353 | unique_function(unique_function &&) = default; | |||
354 | unique_function(const unique_function &) = delete; | |||
355 | unique_function &operator=(unique_function &&) = default; | |||
356 | unique_function &operator=(const unique_function &) = delete; | |||
357 | ||||
358 | template <typename CallableT> | |||
359 | unique_function( | |||
360 | CallableT Callable, | |||
361 | detail::EnableUnlessSameType<CallableT, unique_function> * = nullptr, | |||
362 | detail::EnableIfCallable<CallableT, R, P...> * = nullptr) | |||
363 | : Base(std::forward<CallableT>(Callable), | |||
364 | typename Base::template CalledAs<CallableT>{}) {} | |||
365 | ||||
366 | R operator()(P... Params) { | |||
367 | return this->getCallPtr()(this->getCalleePtr(), Params...); | |||
368 | } | |||
369 | }; | |||
370 | ||||
371 | template <typename R, typename... P> | |||
372 | class unique_function<R(P...) const> | |||
373 | : public detail::UniqueFunctionBase<R, P...> { | |||
374 | using Base = detail::UniqueFunctionBase<R, P...>; | |||
375 | ||||
376 | public: | |||
377 | unique_function() = default; | |||
378 | unique_function(std::nullptr_t) {} | |||
379 | unique_function(unique_function &&) = default; | |||
380 | unique_function(const unique_function &) = delete; | |||
381 | unique_function &operator=(unique_function &&) = default; | |||
382 | unique_function &operator=(const unique_function &) = delete; | |||
383 | ||||
384 | template <typename CallableT> | |||
385 | unique_function( | |||
386 | CallableT Callable, | |||
387 | detail::EnableUnlessSameType<CallableT, unique_function> * = nullptr, | |||
388 | detail::EnableIfCallable<const CallableT, R, P...> * = nullptr) | |||
389 | : Base(std::forward<CallableT>(Callable), | |||
390 | typename Base::template CalledAs<const CallableT>{}) {} | |||
391 | ||||
392 | R operator()(P... Params) const { | |||
393 | return this->getCallPtr()(this->getCalleePtr(), Params...); | |||
394 | } | |||
395 | }; | |||
396 | ||||
397 | } // end namespace llvm | |||
398 | ||||
399 | #endif // LLVM_ADT_FUNCTIONEXTRAS_H |