Bug Summary

File:llvm/include/llvm/ADT/FunctionExtras.h
Warning:line 142, column 5
Undefined or garbage value returned to caller

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name Core.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-11/lib/clang/11.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/lib/ExecutionEngine/Orc -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-11/lib/clang/11.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/lib/ExecutionEngine/Orc -fdebug-prefix-map=/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-03-09-184146-41876-1 -x c++ /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp

/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp

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/OrcError.h"
14#include "llvm/Support/CommandLine.h"
15#include "llvm/Support/Debug.h"
16#include "llvm/Support/Format.h"
17
18#include <condition_variable>
19#if LLVM_ENABLE_THREADS1
20#include <future>
21#endif
22
23#define DEBUG_TYPE"orc" "orc"
24
25using namespace llvm;
26
27namespace {
28
29#ifndef NDEBUG
30
31cl::opt<bool> PrintHidden("debug-orc-print-hidden", cl::init(true),
32 cl::desc("debug print hidden symbols defined by "
33 "materialization units"),
34 cl::Hidden);
35
36cl::opt<bool> PrintCallable("debug-orc-print-callable", cl::init(true),
37 cl::desc("debug print callable symbols defined by "
38 "materialization units"),
39 cl::Hidden);
40
41cl::opt<bool> PrintData("debug-orc-print-data", cl::init(true),
42 cl::desc("debug print data symbols defined by "
43 "materialization units"),
44 cl::Hidden);
45
46#endif // NDEBUG
47
48// SetPrinter predicate that prints every element.
49template <typename T> struct PrintAll {
50 bool operator()(const T &E) { return true; }
51};
52
53bool anyPrintSymbolOptionSet() {
54#ifndef NDEBUG
55 return PrintHidden || PrintCallable || PrintData;
56#else
57 return false;
58#endif // NDEBUG
59}
60
61bool flagsMatchCLOpts(const JITSymbolFlags &Flags) {
62#ifndef NDEBUG
63 // Bail out early if this is a hidden symbol and we're not printing hiddens.
64 if (!PrintHidden && !Flags.isExported())
65 return false;
66
67 // Return true if this is callable and we're printing callables.
68 if (PrintCallable && Flags.isCallable())
69 return true;
70
71 // Return true if this is data and we're printing data.
72 if (PrintData && !Flags.isCallable())
73 return true;
74
75 // otherwise return false.
76 return false;
77#else
78 return false;
79#endif // NDEBUG
80}
81
82// Prints a sequence of items, filtered by an user-supplied predicate.
83template <typename Sequence,
84 typename Pred = PrintAll<typename Sequence::value_type>>
85class SequencePrinter {
86public:
87 SequencePrinter(const Sequence &S, char OpenSeq, char CloseSeq,
88 Pred ShouldPrint = Pred())
89 : S(S), OpenSeq(OpenSeq), CloseSeq(CloseSeq),
90 ShouldPrint(std::move(ShouldPrint)) {}
91
92 void printTo(llvm::raw_ostream &OS) const {
93 bool PrintComma = false;
94 OS << OpenSeq;
95 for (auto &E : S) {
96 if (ShouldPrint(E)) {
97 if (PrintComma)
98 OS << ',';
99 OS << ' ' << E;
100 PrintComma = true;
101 }
102 }
103 OS << ' ' << CloseSeq;
104 }
105
106private:
107 const Sequence &S;
108 char OpenSeq;
109 char CloseSeq;
110 mutable Pred ShouldPrint;
111};
112
113template <typename Sequence, typename Pred>
114SequencePrinter<Sequence, Pred> printSequence(const Sequence &S, char OpenSeq,
115 char CloseSeq, Pred P = Pred()) {
116 return SequencePrinter<Sequence, Pred>(S, OpenSeq, CloseSeq, std::move(P));
117}
118
119// Render a SequencePrinter by delegating to its printTo method.
120template <typename Sequence, typename Pred>
121llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
122 const SequencePrinter<Sequence, Pred> &Printer) {
123 Printer.printTo(OS);
124 return OS;
125}
126
127struct PrintSymbolFlagsMapElemsMatchingCLOpts {
128 bool operator()(const orc::SymbolFlagsMap::value_type &KV) {
129 return flagsMatchCLOpts(KV.second);
130 }
131};
132
133struct PrintSymbolMapElemsMatchingCLOpts {
134 bool operator()(const orc::SymbolMap::value_type &KV) {
135 return flagsMatchCLOpts(KV.second.getFlags());
136 }
137};
138
139} // end anonymous namespace
140
141namespace llvm {
142namespace orc {
143
144char FailedToMaterialize::ID = 0;
145char SymbolsNotFound::ID = 0;
146char SymbolsCouldNotBeRemoved::ID = 0;
147char MissingSymbolDefinitions::ID = 0;
148char UnexpectedSymbolDefinitions::ID = 0;
149
150RegisterDependenciesFunction NoDependenciesToRegister =
151 RegisterDependenciesFunction();
152
153void MaterializationUnit::anchor() {}
154
155raw_ostream &operator<<(raw_ostream &OS, const SymbolStringPtr &Sym) {
156 return OS << *Sym;
157}
158
159raw_ostream &operator<<(raw_ostream &OS, const SymbolNameSet &Symbols) {
160 return OS << printSequence(Symbols, '{', '}', PrintAll<SymbolStringPtr>());
161}
162
163raw_ostream &operator<<(raw_ostream &OS, const SymbolNameVector &Symbols) {
164 return OS << printSequence(Symbols, '[', ']', PrintAll<SymbolStringPtr>());
165}
166
167raw_ostream &operator<<(raw_ostream &OS, const JITSymbolFlags &Flags) {
168 if (Flags.hasError())
169 OS << "[*ERROR*]";
170 if (Flags.isCallable())
171 OS << "[Callable]";
172 else
173 OS << "[Data]";
174 if (Flags.isWeak())
175 OS << "[Weak]";
176 else if (Flags.isCommon())
177 OS << "[Common]";
178
179 if (!Flags.isExported())
180 OS << "[Hidden]";
181
182 return OS;
183}
184
185raw_ostream &operator<<(raw_ostream &OS, const JITEvaluatedSymbol &Sym) {
186 return OS << format("0x%016" PRIx64"l" "x", Sym.getAddress()) << " "
187 << Sym.getFlags();
188}
189
190raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap::value_type &KV) {
191 return OS << "(\"" << KV.first << "\", " << KV.second << ")";
192}
193
194raw_ostream &operator<<(raw_ostream &OS, const SymbolMap::value_type &KV) {
195 return OS << "(\"" << KV.first << "\": " << KV.second << ")";
196}
197
198raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap &SymbolFlags) {
199 return OS << printSequence(SymbolFlags, '{', '}',
200 PrintSymbolFlagsMapElemsMatchingCLOpts());
201}
202
203raw_ostream &operator<<(raw_ostream &OS, const SymbolMap &Symbols) {
204 return OS << printSequence(Symbols, '{', '}',
205 PrintSymbolMapElemsMatchingCLOpts());
206}
207
208raw_ostream &operator<<(raw_ostream &OS,
209 const SymbolDependenceMap::value_type &KV) {
210 return OS << "(" << KV.first->getName() << ", " << KV.second << ")";
211}
212
213raw_ostream &operator<<(raw_ostream &OS, const SymbolDependenceMap &Deps) {
214 return OS << printSequence(Deps, '{', '}',
215 PrintAll<SymbolDependenceMap::value_type>());
216}
217
218raw_ostream &operator<<(raw_ostream &OS, const MaterializationUnit &MU) {
219 OS << "MU@" << &MU << " (\"" << MU.getName() << "\"";
220 if (anyPrintSymbolOptionSet())
221 OS << ", " << MU.getSymbols();
222 return OS << ")";
223}
224
225raw_ostream &operator<<(raw_ostream &OS, const LookupKind &K) {
226 switch (K) {
227 case LookupKind::Static:
228 return OS << "Static";
229 case LookupKind::DLSym:
230 return OS << "DLSym";
231 }
232 llvm_unreachable("Invalid lookup kind")::llvm::llvm_unreachable_internal("Invalid lookup kind", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 232)
;
233}
234
235raw_ostream &operator<<(raw_ostream &OS,
236 const JITDylibLookupFlags &JDLookupFlags) {
237 switch (JDLookupFlags) {
238 case JITDylibLookupFlags::MatchExportedSymbolsOnly:
239 return OS << "MatchExportedSymbolsOnly";
240 case JITDylibLookupFlags::MatchAllSymbols:
241 return OS << "MatchAllSymbols";
242 }
243 llvm_unreachable("Invalid JITDylib lookup flags")::llvm::llvm_unreachable_internal("Invalid JITDylib lookup flags"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 243)
;
244}
245
246raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LookupFlags) {
247 switch (LookupFlags) {
248 case SymbolLookupFlags::RequiredSymbol:
249 return OS << "RequiredSymbol";
250 case SymbolLookupFlags::WeaklyReferencedSymbol:
251 return OS << "WeaklyReferencedSymbol";
252 }
253 llvm_unreachable("Invalid symbol lookup flags")::llvm::llvm_unreachable_internal("Invalid symbol lookup flags"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 253)
;
254}
255
256raw_ostream &operator<<(raw_ostream &OS,
257 const SymbolLookupSet::value_type &KV) {
258 return OS << "(" << KV.first << ", " << KV.second << ")";
259}
260
261raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupSet &LookupSet) {
262 return OS << printSequence(LookupSet, '{', '}',
263 PrintAll<SymbolLookupSet::value_type>());
264}
265
266raw_ostream &operator<<(raw_ostream &OS,
267 const JITDylibSearchOrder &SearchOrder) {
268 OS << "[";
269 if (!SearchOrder.empty()) {
270 assert(SearchOrder.front().first &&((SearchOrder.front().first && "JITDylibList entries must not be null"
) ? static_cast<void> (0) : __assert_fail ("SearchOrder.front().first && \"JITDylibList entries must not be null\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 271, __PRETTY_FUNCTION__))
271 "JITDylibList entries must not be null")((SearchOrder.front().first && "JITDylibList entries must not be null"
) ? static_cast<void> (0) : __assert_fail ("SearchOrder.front().first && \"JITDylibList entries must not be null\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 271, __PRETTY_FUNCTION__))
;
272 OS << " (\"" << SearchOrder.front().first->getName() << "\", "
273 << SearchOrder.begin()->second << ")";
274 for (auto &KV :
275 make_range(std::next(SearchOrder.begin(), 1), SearchOrder.end())) {
276 assert(KV.first && "JITDylibList entries must not be null")((KV.first && "JITDylibList entries must not be null"
) ? static_cast<void> (0) : __assert_fail ("KV.first && \"JITDylibList entries must not be null\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 276, __PRETTY_FUNCTION__))
;
277 OS << ", (\"" << KV.first->getName() << "\", " << KV.second << ")";
278 }
279 }
280 OS << " ]";
281 return OS;
282}
283
284raw_ostream &operator<<(raw_ostream &OS, const SymbolAliasMap &Aliases) {
285 OS << "{";
286 for (auto &KV : Aliases)
287 OS << " " << *KV.first << ": " << KV.second.Aliasee << " "
288 << KV.second.AliasFlags;
289 OS << " }";
290 return OS;
291}
292
293raw_ostream &operator<<(raw_ostream &OS, const SymbolState &S) {
294 switch (S) {
295 case SymbolState::Invalid:
296 return OS << "Invalid";
297 case SymbolState::NeverSearched:
298 return OS << "Never-Searched";
299 case SymbolState::Materializing:
300 return OS << "Materializing";
301 case SymbolState::Resolved:
302 return OS << "Resolved";
303 case SymbolState::Emitted:
304 return OS << "Emitted";
305 case SymbolState::Ready:
306 return OS << "Ready";
307 }
308 llvm_unreachable("Invalid state")::llvm::llvm_unreachable_internal("Invalid state", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 308)
;
309}
310
311FailedToMaterialize::FailedToMaterialize(
312 std::shared_ptr<SymbolDependenceMap> Symbols)
313 : Symbols(std::move(Symbols)) {
314 assert(!this->Symbols->empty() && "Can not fail to resolve an empty set")((!this->Symbols->empty() && "Can not fail to resolve an empty set"
) ? static_cast<void> (0) : __assert_fail ("!this->Symbols->empty() && \"Can not fail to resolve an empty set\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 314, __PRETTY_FUNCTION__))
;
315}
316
317std::error_code FailedToMaterialize::convertToErrorCode() const {
318 return orcError(OrcErrorCode::UnknownORCError);
319}
320
321void FailedToMaterialize::log(raw_ostream &OS) const {
322 OS << "Failed to materialize symbols: " << *Symbols;
323}
324
325SymbolsNotFound::SymbolsNotFound(SymbolNameSet Symbols) {
326 for (auto &Sym : Symbols)
327 this->Symbols.push_back(Sym);
328 assert(!this->Symbols.empty() && "Can not fail to resolve an empty set")((!this->Symbols.empty() && "Can not fail to resolve an empty set"
) ? static_cast<void> (0) : __assert_fail ("!this->Symbols.empty() && \"Can not fail to resolve an empty set\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 328, __PRETTY_FUNCTION__))
;
329}
330
331SymbolsNotFound::SymbolsNotFound(SymbolNameVector Symbols)
332 : Symbols(std::move(Symbols)) {
333 assert(!this->Symbols.empty() && "Can not fail to resolve an empty set")((!this->Symbols.empty() && "Can not fail to resolve an empty set"
) ? static_cast<void> (0) : __assert_fail ("!this->Symbols.empty() && \"Can not fail to resolve an empty set\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 333, __PRETTY_FUNCTION__))
;
334}
335
336std::error_code SymbolsNotFound::convertToErrorCode() const {
337 return orcError(OrcErrorCode::UnknownORCError);
338}
339
340void SymbolsNotFound::log(raw_ostream &OS) const {
341 OS << "Symbols not found: " << Symbols;
342}
343
344SymbolsCouldNotBeRemoved::SymbolsCouldNotBeRemoved(SymbolNameSet Symbols)
345 : Symbols(std::move(Symbols)) {
346 assert(!this->Symbols.empty() && "Can not fail to resolve an empty set")((!this->Symbols.empty() && "Can not fail to resolve an empty set"
) ? static_cast<void> (0) : __assert_fail ("!this->Symbols.empty() && \"Can not fail to resolve an empty set\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 346, __PRETTY_FUNCTION__))
;
347}
348
349std::error_code SymbolsCouldNotBeRemoved::convertToErrorCode() const {
350 return orcError(OrcErrorCode::UnknownORCError);
351}
352
353void SymbolsCouldNotBeRemoved::log(raw_ostream &OS) const {
354 OS << "Symbols could not be removed: " << Symbols;
355}
356
357std::error_code MissingSymbolDefinitions::convertToErrorCode() const {
358 return orcError(OrcErrorCode::MissingSymbolDefinitions);
359}
360
361void MissingSymbolDefinitions::log(raw_ostream &OS) const {
362 OS << "Missing definitions in module " << ModuleName
363 << ": " << Symbols;
364}
365
366std::error_code UnexpectedSymbolDefinitions::convertToErrorCode() const {
367 return orcError(OrcErrorCode::UnexpectedSymbolDefinitions);
368}
369
370void UnexpectedSymbolDefinitions::log(raw_ostream &OS) const {
371 OS << "Unexpected definitions in module " << ModuleName
372 << ": " << Symbols;
373}
374
375AsynchronousSymbolQuery::AsynchronousSymbolQuery(
376 const SymbolLookupSet &Symbols, SymbolState RequiredState,
377 SymbolsResolvedCallback NotifyComplete)
378 : NotifyComplete(std::move(NotifyComplete)), RequiredState(RequiredState) {
379 assert(RequiredState >= SymbolState::Resolved &&((RequiredState >= SymbolState::Resolved && "Cannot query for a symbols that have not reached the resolve state "
"yet") ? static_cast<void> (0) : __assert_fail ("RequiredState >= SymbolState::Resolved && \"Cannot query for a symbols that have not reached the resolve state \" \"yet\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 381, __PRETTY_FUNCTION__))
380 "Cannot query for a symbols that have not reached the resolve state "((RequiredState >= SymbolState::Resolved && "Cannot query for a symbols that have not reached the resolve state "
"yet") ? static_cast<void> (0) : __assert_fail ("RequiredState >= SymbolState::Resolved && \"Cannot query for a symbols that have not reached the resolve state \" \"yet\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 381, __PRETTY_FUNCTION__))
381 "yet")((RequiredState >= SymbolState::Resolved && "Cannot query for a symbols that have not reached the resolve state "
"yet") ? static_cast<void> (0) : __assert_fail ("RequiredState >= SymbolState::Resolved && \"Cannot query for a symbols that have not reached the resolve state \" \"yet\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 381, __PRETTY_FUNCTION__))
;
382
383 OutstandingSymbolsCount = Symbols.size();
384
385 for (auto &KV : Symbols)
386 ResolvedSymbols[KV.first] = nullptr;
387}
388
389void AsynchronousSymbolQuery::notifySymbolMetRequiredState(
390 const SymbolStringPtr &Name, JITEvaluatedSymbol Sym) {
391 auto I = ResolvedSymbols.find(Name);
392 assert(I != ResolvedSymbols.end() &&((I != ResolvedSymbols.end() && "Resolving symbol outside the requested set"
) ? static_cast<void> (0) : __assert_fail ("I != ResolvedSymbols.end() && \"Resolving symbol outside the requested set\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 393, __PRETTY_FUNCTION__))
393 "Resolving symbol outside the requested set")((I != ResolvedSymbols.end() && "Resolving symbol outside the requested set"
) ? static_cast<void> (0) : __assert_fail ("I != ResolvedSymbols.end() && \"Resolving symbol outside the requested set\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 393, __PRETTY_FUNCTION__))
;
394 assert(I->second.getAddress() == 0 && "Redundantly resolving symbol Name")((I->second.getAddress() == 0 && "Redundantly resolving symbol Name"
) ? static_cast<void> (0) : __assert_fail ("I->second.getAddress() == 0 && \"Redundantly resolving symbol Name\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 394, __PRETTY_FUNCTION__))
;
395 I->second = std::move(Sym);
396 --OutstandingSymbolsCount;
397}
398
399void AsynchronousSymbolQuery::handleComplete() {
400 assert(OutstandingSymbolsCount == 0 &&((OutstandingSymbolsCount == 0 && "Symbols remain, handleComplete called prematurely"
) ? static_cast<void> (0) : __assert_fail ("OutstandingSymbolsCount == 0 && \"Symbols remain, handleComplete called prematurely\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 401, __PRETTY_FUNCTION__))
8
Assuming field 'OutstandingSymbolsCount' is equal to 0
9
'?' condition is true
401 "Symbols remain, handleComplete called prematurely")((OutstandingSymbolsCount == 0 && "Symbols remain, handleComplete called prematurely"
) ? static_cast<void> (0) : __assert_fail ("OutstandingSymbolsCount == 0 && \"Symbols remain, handleComplete called prematurely\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 401, __PRETTY_FUNCTION__))
;
402
403 auto TmpNotifyComplete = std::move(NotifyComplete);
10
Calling move constructor for 'unique_function<void (llvm::Expected<llvm::DenseMap<llvm::orc::SymbolStringPtr, llvm::JITEvaluatedSymbol, llvm::DenseMapInfo<orc::SymbolStringPtr>, llvm::detail::DenseMapPair<llvm::orc::SymbolStringPtr, llvm::JITEvaluatedSymbol> > >)>'
13
Returning from move constructor for 'unique_function<void (llvm::Expected<llvm::DenseMap<llvm::orc::SymbolStringPtr, llvm::JITEvaluatedSymbol, llvm::DenseMapInfo<orc::SymbolStringPtr>, llvm::detail::DenseMapPair<llvm::orc::SymbolStringPtr, llvm::JITEvaluatedSymbol> > >)>'
404 NotifyComplete = SymbolsResolvedCallback();
405 TmpNotifyComplete(std::move(ResolvedSymbols));
14
Calling 'unique_function::operator()'
406}
407
408bool AsynchronousSymbolQuery::canStillFail() { return !!NotifyComplete; }
409
410void AsynchronousSymbolQuery::handleFailed(Error Err) {
411 assert(QueryRegistrations.empty() && ResolvedSymbols.empty() &&((QueryRegistrations.empty() && ResolvedSymbols.empty
() && OutstandingSymbolsCount == 0 && "Query should already have been abandoned"
) ? static_cast<void> (0) : __assert_fail ("QueryRegistrations.empty() && ResolvedSymbols.empty() && OutstandingSymbolsCount == 0 && \"Query should already have been abandoned\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 413, __PRETTY_FUNCTION__))
412 OutstandingSymbolsCount == 0 &&((QueryRegistrations.empty() && ResolvedSymbols.empty
() && OutstandingSymbolsCount == 0 && "Query should already have been abandoned"
) ? static_cast<void> (0) : __assert_fail ("QueryRegistrations.empty() && ResolvedSymbols.empty() && OutstandingSymbolsCount == 0 && \"Query should already have been abandoned\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 413, __PRETTY_FUNCTION__))
413 "Query should already have been abandoned")((QueryRegistrations.empty() && ResolvedSymbols.empty
() && OutstandingSymbolsCount == 0 && "Query should already have been abandoned"
) ? static_cast<void> (0) : __assert_fail ("QueryRegistrations.empty() && ResolvedSymbols.empty() && OutstandingSymbolsCount == 0 && \"Query should already have been abandoned\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 413, __PRETTY_FUNCTION__))
;
414 NotifyComplete(std::move(Err));
415 NotifyComplete = SymbolsResolvedCallback();
416}
417
418void AsynchronousSymbolQuery::addQueryDependence(JITDylib &JD,
419 SymbolStringPtr Name) {
420 bool Added = QueryRegistrations[&JD].insert(std::move(Name)).second;
421 (void)Added;
422 assert(Added && "Duplicate dependence notification?")((Added && "Duplicate dependence notification?") ? static_cast
<void> (0) : __assert_fail ("Added && \"Duplicate dependence notification?\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 422, __PRETTY_FUNCTION__))
;
423}
424
425void AsynchronousSymbolQuery::removeQueryDependence(
426 JITDylib &JD, const SymbolStringPtr &Name) {
427 auto QRI = QueryRegistrations.find(&JD);
428 assert(QRI != QueryRegistrations.end() &&((QRI != QueryRegistrations.end() && "No dependencies registered for JD"
) ? static_cast<void> (0) : __assert_fail ("QRI != QueryRegistrations.end() && \"No dependencies registered for JD\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 429, __PRETTY_FUNCTION__))
429 "No dependencies registered for JD")((QRI != QueryRegistrations.end() && "No dependencies registered for JD"
) ? static_cast<void> (0) : __assert_fail ("QRI != QueryRegistrations.end() && \"No dependencies registered for JD\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 429, __PRETTY_FUNCTION__))
;
430 assert(QRI->second.count(Name) && "No dependency on Name in JD")((QRI->second.count(Name) && "No dependency on Name in JD"
) ? static_cast<void> (0) : __assert_fail ("QRI->second.count(Name) && \"No dependency on Name in JD\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 430, __PRETTY_FUNCTION__))
;
431 QRI->second.erase(Name);
432 if (QRI->second.empty())
433 QueryRegistrations.erase(QRI);
434}
435
436void AsynchronousSymbolQuery::detach() {
437 ResolvedSymbols.clear();
438 OutstandingSymbolsCount = 0;
439 for (auto &KV : QueryRegistrations)
440 KV.first->detachQueryHelper(*this, KV.second);
441 QueryRegistrations.clear();
442}
443
444MaterializationResponsibility::~MaterializationResponsibility() {
445 assert(SymbolFlags.empty() &&((SymbolFlags.empty() && "All symbols should have been explicitly materialized or failed"
) ? static_cast<void> (0) : __assert_fail ("SymbolFlags.empty() && \"All symbols should have been explicitly materialized or failed\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 446, __PRETTY_FUNCTION__))
446 "All symbols should have been explicitly materialized or failed")((SymbolFlags.empty() && "All symbols should have been explicitly materialized or failed"
) ? static_cast<void> (0) : __assert_fail ("SymbolFlags.empty() && \"All symbols should have been explicitly materialized or failed\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 446, __PRETTY_FUNCTION__))
;
447}
448
449SymbolNameSet MaterializationResponsibility::getRequestedSymbols() const {
450 return JD.getRequestedSymbols(SymbolFlags);
451}
452
453Error MaterializationResponsibility::notifyResolved(const SymbolMap &Symbols) {
454 LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { dbgs() << "In " << JD.getName() <<
" resolving " << Symbols << "\n"; }; } } while (
false)
455 dbgs() << "In " << JD.getName() << " resolving " << Symbols << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { dbgs() << "In " << JD.getName() <<
" resolving " << Symbols << "\n"; }; } } while (
false)
456 })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { dbgs() << "In " << JD.getName() <<
" resolving " << Symbols << "\n"; }; } } while (
false)
;
457#ifndef NDEBUG
458 for (auto &KV : Symbols) {
459 auto WeakFlags = JITSymbolFlags::Weak | JITSymbolFlags::Common;
460 auto I = SymbolFlags.find(KV.first);
461 assert(I != SymbolFlags.end() &&((I != SymbolFlags.end() && "Resolving symbol outside this responsibility set"
) ? static_cast<void> (0) : __assert_fail ("I != SymbolFlags.end() && \"Resolving symbol outside this responsibility set\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 462, __PRETTY_FUNCTION__))
462 "Resolving symbol outside this responsibility set")((I != SymbolFlags.end() && "Resolving symbol outside this responsibility set"
) ? static_cast<void> (0) : __assert_fail ("I != SymbolFlags.end() && \"Resolving symbol outside this responsibility set\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 462, __PRETTY_FUNCTION__))
;
463 assert((KV.second.getFlags() & ~WeakFlags) == (I->second & ~WeakFlags) &&(((KV.second.getFlags() & ~WeakFlags) == (I->second &
~WeakFlags) && "Resolving symbol with incorrect flags"
) ? static_cast<void> (0) : __assert_fail ("(KV.second.getFlags() & ~WeakFlags) == (I->second & ~WeakFlags) && \"Resolving symbol with incorrect flags\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 464, __PRETTY_FUNCTION__))
464 "Resolving symbol with incorrect flags")(((KV.second.getFlags() & ~WeakFlags) == (I->second &
~WeakFlags) && "Resolving symbol with incorrect flags"
) ? static_cast<void> (0) : __assert_fail ("(KV.second.getFlags() & ~WeakFlags) == (I->second & ~WeakFlags) && \"Resolving symbol with incorrect flags\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 464, __PRETTY_FUNCTION__))
;
465 }
466#endif
467
468 return JD.resolve(Symbols);
469}
470
471Error MaterializationResponsibility::notifyEmitted() {
472
473 LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { dbgs() << "In " << JD.getName() <<
" emitting " << SymbolFlags << "\n"; }; } } while
(false)
474 dbgs() << "In " << JD.getName() << " emitting " << SymbolFlags << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { dbgs() << "In " << JD.getName() <<
" emitting " << SymbolFlags << "\n"; }; } } while
(false)
475 })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { dbgs() << "In " << JD.getName() <<
" emitting " << SymbolFlags << "\n"; }; } } while
(false)
;
476
477 if (auto Err = JD.emit(SymbolFlags))
478 return Err;
479
480 SymbolFlags.clear();
481 return Error::success();
482}
483
484Error MaterializationResponsibility::defineMaterializing(
485 SymbolFlagsMap NewSymbolFlags) {
486
487 LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { dbgs() << "In " << JD.getName() <<
" defining materializing symbols " << NewSymbolFlags <<
"\n"; }; } } while (false)
488 dbgs() << "In " << JD.getName() << " defining materializing symbols "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { dbgs() << "In " << JD.getName() <<
" defining materializing symbols " << NewSymbolFlags <<
"\n"; }; } } while (false)
489 << NewSymbolFlags << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { dbgs() << "In " << JD.getName() <<
" defining materializing symbols " << NewSymbolFlags <<
"\n"; }; } } while (false)
490 })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { dbgs() << "In " << JD.getName() <<
" defining materializing symbols " << NewSymbolFlags <<
"\n"; }; } } while (false)
;
491 if (auto AcceptedDefs = JD.defineMaterializing(std::move(NewSymbolFlags))) {
492 // Add all newly accepted symbols to this responsibility object.
493 for (auto &KV : *AcceptedDefs)
494 SymbolFlags.insert(KV);
495 return Error::success();
496 } else
497 return AcceptedDefs.takeError();
498}
499
500void MaterializationResponsibility::failMaterialization() {
501
502 LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { dbgs() << "In " << JD.getName() <<
" failing materialization for " << SymbolFlags <<
"\n"; }; } } while (false)
503 dbgs() << "In " << JD.getName() << " failing materialization for "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { dbgs() << "In " << JD.getName() <<
" failing materialization for " << SymbolFlags <<
"\n"; }; } } while (false)
504 << SymbolFlags << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { dbgs() << "In " << JD.getName() <<
" failing materialization for " << SymbolFlags <<
"\n"; }; } } while (false)
505 })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { dbgs() << "In " << JD.getName() <<
" failing materialization for " << SymbolFlags <<
"\n"; }; } } while (false)
;
506
507 JITDylib::FailedSymbolsWorklist Worklist;
508
509 for (auto &KV : SymbolFlags)
510 Worklist.push_back(std::make_pair(&JD, KV.first));
511 SymbolFlags.clear();
512
513 JD.notifyFailed(std::move(Worklist));
514}
515
516void MaterializationResponsibility::replace(
517 std::unique_ptr<MaterializationUnit> MU) {
518
519 for (auto &KV : MU->getSymbols())
520 SymbolFlags.erase(KV.first);
521
522 if (MU->getInitializerSymbol() == InitSymbol)
523 InitSymbol = nullptr;
524
525 LLVM_DEBUG(JD.getExecutionSession().runSessionLocked([&]() {do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { JD.getExecutionSession().runSessionLocked([&](
) { dbgs() << "In " << JD.getName() << " replacing symbols with "
<< *MU << "\n"; });; } } while (false)
526 dbgs() << "In " << JD.getName() << " replacing symbols with " << *MUdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { JD.getExecutionSession().runSessionLocked([&](
) { dbgs() << "In " << JD.getName() << " replacing symbols with "
<< *MU << "\n"; });; } } while (false)
527 << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { JD.getExecutionSession().runSessionLocked([&](
) { dbgs() << "In " << JD.getName() << " replacing symbols with "
<< *MU << "\n"; });; } } while (false)
528 });)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { JD.getExecutionSession().runSessionLocked([&](
) { dbgs() << "In " << JD.getName() << " replacing symbols with "
<< *MU << "\n"; });; } } while (false)
;
529
530 JD.replace(std::move(MU));
531}
532
533MaterializationResponsibility
534MaterializationResponsibility::delegate(const SymbolNameSet &Symbols,
535 VModuleKey NewKey) {
536
537 if (NewKey == VModuleKey())
538 NewKey = K;
539
540 SymbolStringPtr DelegatedInitSymbol;
541 SymbolFlagsMap DelegatedFlags;
542
543 for (auto &Name : Symbols) {
544 auto I = SymbolFlags.find(Name);
545 assert(I != SymbolFlags.end() &&((I != SymbolFlags.end() && "Symbol is not tracked by this MaterializationResponsibility "
"instance") ? static_cast<void> (0) : __assert_fail ("I != SymbolFlags.end() && \"Symbol is not tracked by this MaterializationResponsibility \" \"instance\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 547, __PRETTY_FUNCTION__))
546 "Symbol is not tracked by this MaterializationResponsibility "((I != SymbolFlags.end() && "Symbol is not tracked by this MaterializationResponsibility "
"instance") ? static_cast<void> (0) : __assert_fail ("I != SymbolFlags.end() && \"Symbol is not tracked by this MaterializationResponsibility \" \"instance\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 547, __PRETTY_FUNCTION__))
547 "instance")((I != SymbolFlags.end() && "Symbol is not tracked by this MaterializationResponsibility "
"instance") ? static_cast<void> (0) : __assert_fail ("I != SymbolFlags.end() && \"Symbol is not tracked by this MaterializationResponsibility \" \"instance\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 547, __PRETTY_FUNCTION__))
;
548
549 DelegatedFlags[Name] = std::move(I->second);
550 if (Name == InitSymbol)
551 std::swap(InitSymbol, DelegatedInitSymbol);
552
553 SymbolFlags.erase(I);
554 }
555
556 return MaterializationResponsibility(JD, std::move(DelegatedFlags),
557 std::move(DelegatedInitSymbol),
558 std::move(NewKey));
559}
560
561void MaterializationResponsibility::addDependencies(
562 const SymbolStringPtr &Name, const SymbolDependenceMap &Dependencies) {
563 assert(SymbolFlags.count(Name) &&((SymbolFlags.count(Name) && "Symbol not covered by this MaterializationResponsibility instance"
) ? static_cast<void> (0) : __assert_fail ("SymbolFlags.count(Name) && \"Symbol not covered by this MaterializationResponsibility instance\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 564, __PRETTY_FUNCTION__))
564 "Symbol not covered by this MaterializationResponsibility instance")((SymbolFlags.count(Name) && "Symbol not covered by this MaterializationResponsibility instance"
) ? static_cast<void> (0) : __assert_fail ("SymbolFlags.count(Name) && \"Symbol not covered by this MaterializationResponsibility instance\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 564, __PRETTY_FUNCTION__))
;
565 JD.addDependencies(Name, Dependencies);
566}
567
568void MaterializationResponsibility::addDependenciesForAll(
569 const SymbolDependenceMap &Dependencies) {
570 for (auto &KV : SymbolFlags)
571 JD.addDependencies(KV.first, Dependencies);
572}
573
574AbsoluteSymbolsMaterializationUnit::AbsoluteSymbolsMaterializationUnit(
575 SymbolMap Symbols, VModuleKey K)
576 : MaterializationUnit(extractFlags(Symbols), nullptr, std::move(K)),
577 Symbols(std::move(Symbols)) {}
578
579StringRef AbsoluteSymbolsMaterializationUnit::getName() const {
580 return "<Absolute Symbols>";
581}
582
583void AbsoluteSymbolsMaterializationUnit::materialize(
584 MaterializationResponsibility R) {
585 // No dependencies, so these calls can't fail.
586 cantFail(R.notifyResolved(Symbols));
587 cantFail(R.notifyEmitted());
588}
589
590void AbsoluteSymbolsMaterializationUnit::discard(const JITDylib &JD,
591 const SymbolStringPtr &Name) {
592 assert(Symbols.count(Name) && "Symbol is not part of this MU")((Symbols.count(Name) && "Symbol is not part of this MU"
) ? static_cast<void> (0) : __assert_fail ("Symbols.count(Name) && \"Symbol is not part of this MU\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 592, __PRETTY_FUNCTION__))
;
593 Symbols.erase(Name);
594}
595
596SymbolFlagsMap
597AbsoluteSymbolsMaterializationUnit::extractFlags(const SymbolMap &Symbols) {
598 SymbolFlagsMap Flags;
599 for (const auto &KV : Symbols)
600 Flags[KV.first] = KV.second.getFlags();
601 return Flags;
602}
603
604ReExportsMaterializationUnit::ReExportsMaterializationUnit(
605 JITDylib *SourceJD, JITDylibLookupFlags SourceJDLookupFlags,
606 SymbolAliasMap Aliases, VModuleKey K)
607 : MaterializationUnit(extractFlags(Aliases), nullptr, std::move(K)),
608 SourceJD(SourceJD), SourceJDLookupFlags(SourceJDLookupFlags),
609 Aliases(std::move(Aliases)) {}
610
611StringRef ReExportsMaterializationUnit::getName() const {
612 return "<Reexports>";
613}
614
615void ReExportsMaterializationUnit::materialize(
616 MaterializationResponsibility R) {
617
618 auto &ES = R.getTargetJITDylib().getExecutionSession();
619 JITDylib &TgtJD = R.getTargetJITDylib();
620 JITDylib &SrcJD = SourceJD ? *SourceJD : TgtJD;
621
622 // Find the set of requested aliases and aliasees. Return any unrequested
623 // aliases back to the JITDylib so as to not prematurely materialize any
624 // aliasees.
625 auto RequestedSymbols = R.getRequestedSymbols();
626 SymbolAliasMap RequestedAliases;
627
628 for (auto &Name : RequestedSymbols) {
629 auto I = Aliases.find(Name);
630 assert(I != Aliases.end() && "Symbol not found in aliases map?")((I != Aliases.end() && "Symbol not found in aliases map?"
) ? static_cast<void> (0) : __assert_fail ("I != Aliases.end() && \"Symbol not found in aliases map?\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 630, __PRETTY_FUNCTION__))
;
631 RequestedAliases[Name] = std::move(I->second);
632 Aliases.erase(I);
633 }
634
635 LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { ES.runSessionLocked([&]() { dbgs() << "materializing reexports: target = "
<< TgtJD.getName() << ", source = " << SrcJD
.getName() << " " << RequestedAliases << "\n"
; }); }; } } while (false)
636 ES.runSessionLocked([&]() {do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { ES.runSessionLocked([&]() { dbgs() << "materializing reexports: target = "
<< TgtJD.getName() << ", source = " << SrcJD
.getName() << " " << RequestedAliases << "\n"
; }); }; } } while (false)
637 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)
638 << ", 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)
639 << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { ES.runSessionLocked([&]() { dbgs() << "materializing reexports: target = "
<< TgtJD.getName() << ", source = " << SrcJD
.getName() << " " << RequestedAliases << "\n"
; }); }; } } while (false)
640 });do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { ES.runSessionLocked([&]() { dbgs() << "materializing reexports: target = "
<< TgtJD.getName() << ", source = " << SrcJD
.getName() << " " << RequestedAliases << "\n"
; }); }; } } while (false)
641 })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { ES.runSessionLocked([&]() { dbgs() << "materializing reexports: target = "
<< TgtJD.getName() << ", source = " << SrcJD
.getName() << " " << RequestedAliases << "\n"
; }); }; } } while (false)
;
642
643 if (!Aliases.empty()) {
644 if (SourceJD)
645 R.replace(reexports(*SourceJD, std::move(Aliases), SourceJDLookupFlags));
646 else
647 R.replace(symbolAliases(std::move(Aliases)));
648 }
649
650 // The OnResolveInfo struct will hold the aliases and responsibilty for each
651 // query in the list.
652 struct OnResolveInfo {
653 OnResolveInfo(MaterializationResponsibility R, SymbolAliasMap Aliases)
654 : R(std::move(R)), Aliases(std::move(Aliases)) {}
655
656 MaterializationResponsibility R;
657 SymbolAliasMap Aliases;
658 };
659
660 // Build a list of queries to issue. In each round we build the largest set of
661 // aliases that we can resolve without encountering a chain definition of the
662 // form Foo -> Bar, Bar -> Baz. Such a form would deadlock as the query would
663 // be waitin on a symbol that it itself had to resolve. Usually this will just
664 // involve one round and a single query.
665
666 std::vector<std::pair<SymbolLookupSet, std::shared_ptr<OnResolveInfo>>>
667 QueryInfos;
668 while (!RequestedAliases.empty()) {
669 SymbolNameSet ResponsibilitySymbols;
670 SymbolLookupSet QuerySymbols;
671 SymbolAliasMap QueryAliases;
672
673 // Collect as many aliases as we can without including a chain.
674 for (auto &KV : RequestedAliases) {
675 // Chain detected. Skip this symbol for this round.
676 if (&SrcJD == &TgtJD && (QueryAliases.count(KV.second.Aliasee) ||
677 RequestedAliases.count(KV.second.Aliasee)))
678 continue;
679
680 ResponsibilitySymbols.insert(KV.first);
681 QuerySymbols.add(KV.second.Aliasee);
682 QueryAliases[KV.first] = std::move(KV.second);
683 }
684
685 // Remove the aliases collected this round from the RequestedAliases map.
686 for (auto &KV : QueryAliases)
687 RequestedAliases.erase(KV.first);
688
689 assert(!QuerySymbols.empty() && "Alias cycle detected!")((!QuerySymbols.empty() && "Alias cycle detected!") ?
static_cast<void> (0) : __assert_fail ("!QuerySymbols.empty() && \"Alias cycle detected!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 689, __PRETTY_FUNCTION__))
;
690
691 auto QueryInfo = std::make_shared<OnResolveInfo>(
692 R.delegate(ResponsibilitySymbols), std::move(QueryAliases));
693 QueryInfos.push_back(
694 make_pair(std::move(QuerySymbols), std::move(QueryInfo)));
695 }
696
697 // Issue the queries.
698 while (!QueryInfos.empty()) {
699 auto QuerySymbols = std::move(QueryInfos.back().first);
700 auto QueryInfo = std::move(QueryInfos.back().second);
701
702 QueryInfos.pop_back();
703
704 auto RegisterDependencies = [QueryInfo,
705 &SrcJD](const SymbolDependenceMap &Deps) {
706 // If there were no materializing symbols, just bail out.
707 if (Deps.empty())
708 return;
709
710 // Otherwise the only deps should be on SrcJD.
711 assert(Deps.size() == 1 && Deps.count(&SrcJD) &&((Deps.size() == 1 && Deps.count(&SrcJD) &&
"Unexpected dependencies for reexports") ? static_cast<void
> (0) : __assert_fail ("Deps.size() == 1 && Deps.count(&SrcJD) && \"Unexpected dependencies for reexports\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 712, __PRETTY_FUNCTION__))
712 "Unexpected dependencies for reexports")((Deps.size() == 1 && Deps.count(&SrcJD) &&
"Unexpected dependencies for reexports") ? static_cast<void
> (0) : __assert_fail ("Deps.size() == 1 && Deps.count(&SrcJD) && \"Unexpected dependencies for reexports\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 712, __PRETTY_FUNCTION__))
;
713
714 auto &SrcJDDeps = Deps.find(&SrcJD)->second;
715 SymbolDependenceMap PerAliasDepsMap;
716 auto &PerAliasDeps = PerAliasDepsMap[&SrcJD];
717
718 for (auto &KV : QueryInfo->Aliases)
719 if (SrcJDDeps.count(KV.second.Aliasee)) {
720 PerAliasDeps = {KV.second.Aliasee};
721 QueryInfo->R.addDependencies(KV.first, PerAliasDepsMap);
722 }
723 };
724
725 auto OnComplete = [QueryInfo](Expected<SymbolMap> Result) {
726 auto &ES = QueryInfo->R.getTargetJITDylib().getExecutionSession();
727 if (Result) {
728 SymbolMap ResolutionMap;
729 for (auto &KV : QueryInfo->Aliases) {
730 assert(Result->count(KV.second.Aliasee) &&((Result->count(KV.second.Aliasee) && "Result map missing entry?"
) ? static_cast<void> (0) : __assert_fail ("Result->count(KV.second.Aliasee) && \"Result map missing entry?\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 731, __PRETTY_FUNCTION__))
731 "Result map missing entry?")((Result->count(KV.second.Aliasee) && "Result map missing entry?"
) ? static_cast<void> (0) : __assert_fail ("Result->count(KV.second.Aliasee) && \"Result map missing entry?\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 731, __PRETTY_FUNCTION__))
;
732 ResolutionMap[KV.first] = JITEvaluatedSymbol(
733 (*Result)[KV.second.Aliasee].getAddress(), KV.second.AliasFlags);
734 }
735 if (auto Err = QueryInfo->R.notifyResolved(ResolutionMap)) {
736 ES.reportError(std::move(Err));
737 QueryInfo->R.failMaterialization();
738 return;
739 }
740 if (auto Err = QueryInfo->R.notifyEmitted()) {
741 ES.reportError(std::move(Err));
742 QueryInfo->R.failMaterialization();
743 return;
744 }
745 } else {
746 ES.reportError(Result.takeError());
747 QueryInfo->R.failMaterialization();
748 }
749 };
750
751 ES.lookup(LookupKind::Static,
752 JITDylibSearchOrder({{&SrcJD, SourceJDLookupFlags}}),
753 QuerySymbols, SymbolState::Resolved, std::move(OnComplete),
754 std::move(RegisterDependencies));
755 }
756}
757
758void ReExportsMaterializationUnit::discard(const JITDylib &JD,
759 const SymbolStringPtr &Name) {
760 assert(Aliases.count(Name) &&((Aliases.count(Name) && "Symbol not covered by this MaterializationUnit"
) ? static_cast<void> (0) : __assert_fail ("Aliases.count(Name) && \"Symbol not covered by this MaterializationUnit\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 761, __PRETTY_FUNCTION__))
761 "Symbol not covered by this MaterializationUnit")((Aliases.count(Name) && "Symbol not covered by this MaterializationUnit"
) ? static_cast<void> (0) : __assert_fail ("Aliases.count(Name) && \"Symbol not covered by this MaterializationUnit\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 761, __PRETTY_FUNCTION__))
;
762 Aliases.erase(Name);
763}
764
765SymbolFlagsMap
766ReExportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) {
767 SymbolFlagsMap SymbolFlags;
768 for (auto &KV : Aliases)
769 SymbolFlags[KV.first] = KV.second.AliasFlags;
770
771 return SymbolFlags;
772}
773
774Expected<SymbolAliasMap>
775buildSimpleReexportsAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols) {
776 SymbolLookupSet LookupSet(Symbols);
777 auto Flags = SourceJD.lookupFlags(
778 LookupKind::Static, JITDylibLookupFlags::MatchAllSymbols, LookupSet);
779
780 if (!Flags)
781 return Flags.takeError();
782
783 if (!LookupSet.empty()) {
784 LookupSet.sortByName();
785 return make_error<SymbolsNotFound>(LookupSet.getSymbolNames());
786 }
787
788 SymbolAliasMap Result;
789 for (auto &Name : Symbols) {
790 assert(Flags->count(Name) && "Missing entry in flags map")((Flags->count(Name) && "Missing entry in flags map"
) ? static_cast<void> (0) : __assert_fail ("Flags->count(Name) && \"Missing entry in flags map\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 790, __PRETTY_FUNCTION__))
;
791 Result[Name] = SymbolAliasMapEntry(Name, (*Flags)[Name]);
792 }
793
794 return Result;
795}
796
797ReexportsGenerator::ReexportsGenerator(JITDylib &SourceJD,
798 JITDylibLookupFlags SourceJDLookupFlags,
799 SymbolPredicate Allow)
800 : SourceJD(SourceJD), SourceJDLookupFlags(SourceJDLookupFlags),
801 Allow(std::move(Allow)) {}
802
803Error ReexportsGenerator::tryToGenerate(LookupKind K, JITDylib &JD,
804 JITDylibLookupFlags JDLookupFlags,
805 const SymbolLookupSet &LookupSet) {
806 assert(&JD != &SourceJD && "Cannot re-export from the same dylib")((&JD != &SourceJD && "Cannot re-export from the same dylib"
) ? static_cast<void> (0) : __assert_fail ("&JD != &SourceJD && \"Cannot re-export from the same dylib\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 806, __PRETTY_FUNCTION__))
;
807
808 // Use lookupFlags to find the subset of symbols that match our lookup.
809 auto Flags = SourceJD.lookupFlags(K, JDLookupFlags, LookupSet);
810 if (!Flags)
811 return Flags.takeError();
812
813 // Create an alias map.
814 orc::SymbolAliasMap AliasMap;
815 for (auto &KV : *Flags)
816 if (!Allow || Allow(KV.first))
817 AliasMap[KV.first] = SymbolAliasMapEntry(KV.first, KV.second);
818
819 if (AliasMap.empty())
820 return Error::success();
821
822 // Define the re-exports.
823 return JD.define(reexports(SourceJD, AliasMap, SourceJDLookupFlags));
824}
825
826JITDylib::DefinitionGenerator::~DefinitionGenerator() {}
827
828void JITDylib::removeGenerator(DefinitionGenerator &G) {
829 ES.runSessionLocked([&]() {
830 auto I = std::find_if(DefGenerators.begin(), DefGenerators.end(),
831 [&](const std::unique_ptr<DefinitionGenerator> &H) {
832 return H.get() == &G;
833 });
834 assert(I != DefGenerators.end() && "Generator not found")((I != DefGenerators.end() && "Generator not found") ?
static_cast<void> (0) : __assert_fail ("I != DefGenerators.end() && \"Generator not found\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 834, __PRETTY_FUNCTION__))
;
835 DefGenerators.erase(I);
836 });
837}
838
839Expected<SymbolFlagsMap>
840JITDylib::defineMaterializing(SymbolFlagsMap SymbolFlags) {
841
842 return ES.runSessionLocked([&]() -> Expected<SymbolFlagsMap> {
843 std::vector<SymbolTable::iterator> AddedSyms;
844 std::vector<SymbolFlagsMap::iterator> RejectedWeakDefs;
845
846 for (auto SFItr = SymbolFlags.begin(), SFEnd = SymbolFlags.end();
847 SFItr != SFEnd; ++SFItr) {
848
849 auto &Name = SFItr->first;
850 auto &Flags = SFItr->second;
851
852 auto EntryItr = Symbols.find(Name);
853
854 // If the entry already exists...
855 if (EntryItr != Symbols.end()) {
856
857 // If this is a strong definition then error out.
858 if (!Flags.isWeak()) {
859 // Remove any symbols already added.
860 for (auto &SI : AddedSyms)
861 Symbols.erase(SI);
862
863 // FIXME: Return all duplicates.
864 return make_error<DuplicateDefinition>(std::string(*Name));
865 }
866
867 // Otherwise just make a note to discard this symbol after the loop.
868 RejectedWeakDefs.push_back(SFItr);
869 continue;
870 } else
871 EntryItr =
872 Symbols.insert(std::make_pair(Name, SymbolTableEntry(Flags))).first;
873
874 AddedSyms.push_back(EntryItr);
875 EntryItr->second.setState(SymbolState::Materializing);
876 }
877
878 // Remove any rejected weak definitions from the SymbolFlags map.
879 while (!RejectedWeakDefs.empty()) {
880 SymbolFlags.erase(RejectedWeakDefs.back());
881 RejectedWeakDefs.pop_back();
882 }
883
884 return SymbolFlags;
885 });
886}
887
888void JITDylib::replace(std::unique_ptr<MaterializationUnit> MU) {
889 assert(MU != nullptr && "Can not replace with a null MaterializationUnit")((MU != nullptr && "Can not replace with a null MaterializationUnit"
) ? static_cast<void> (0) : __assert_fail ("MU != nullptr && \"Can not replace with a null MaterializationUnit\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 889, __PRETTY_FUNCTION__))
;
890
891 auto MustRunMU =
892 ES.runSessionLocked([&, this]() -> std::unique_ptr<MaterializationUnit> {
893
894#ifndef NDEBUG
895 for (auto &KV : MU->getSymbols()) {
896 auto SymI = Symbols.find(KV.first);
897 assert(SymI != Symbols.end() && "Replacing unknown symbol")((SymI != Symbols.end() && "Replacing unknown symbol"
) ? static_cast<void> (0) : __assert_fail ("SymI != Symbols.end() && \"Replacing unknown symbol\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 897, __PRETTY_FUNCTION__))
;
898 assert(SymI->second.getState() == SymbolState::Materializing &&((SymI->second.getState() == SymbolState::Materializing &&
"Can not replace a symbol that ha is not materializing") ? static_cast
<void> (0) : __assert_fail ("SymI->second.getState() == SymbolState::Materializing && \"Can not replace a symbol that ha is not materializing\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 899, __PRETTY_FUNCTION__))
899 "Can not replace a symbol that ha is not materializing")((SymI->second.getState() == SymbolState::Materializing &&
"Can not replace a symbol that ha is not materializing") ? static_cast
<void> (0) : __assert_fail ("SymI->second.getState() == SymbolState::Materializing && \"Can not replace a symbol that ha is not materializing\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 899, __PRETTY_FUNCTION__))
;
900 assert(!SymI->second.hasMaterializerAttached() &&((!SymI->second.hasMaterializerAttached() && "Symbol should not have materializer attached already"
) ? static_cast<void> (0) : __assert_fail ("!SymI->second.hasMaterializerAttached() && \"Symbol should not have materializer attached already\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 901, __PRETTY_FUNCTION__))
901 "Symbol should not have materializer attached already")((!SymI->second.hasMaterializerAttached() && "Symbol should not have materializer attached already"
) ? static_cast<void> (0) : __assert_fail ("!SymI->second.hasMaterializerAttached() && \"Symbol should not have materializer attached already\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 901, __PRETTY_FUNCTION__))
;
902 assert(UnmaterializedInfos.count(KV.first) == 0 &&((UnmaterializedInfos.count(KV.first) == 0 && "Symbol being replaced should have no UnmaterializedInfo"
) ? static_cast<void> (0) : __assert_fail ("UnmaterializedInfos.count(KV.first) == 0 && \"Symbol being replaced should have no UnmaterializedInfo\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 903, __PRETTY_FUNCTION__))
903 "Symbol being replaced should have no UnmaterializedInfo")((UnmaterializedInfos.count(KV.first) == 0 && "Symbol being replaced should have no UnmaterializedInfo"
) ? static_cast<void> (0) : __assert_fail ("UnmaterializedInfos.count(KV.first) == 0 && \"Symbol being replaced should have no UnmaterializedInfo\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 903, __PRETTY_FUNCTION__))
;
904 }
905#endif // NDEBUG
906
907 // If any symbol has pending queries against it then we need to
908 // materialize MU immediately.
909 for (auto &KV : MU->getSymbols()) {
910 auto MII = MaterializingInfos.find(KV.first);
911 if (MII != MaterializingInfos.end()) {
912 if (MII->second.hasQueriesPending())
913 return std::move(MU);
914 }
915 }
916
917 // Otherwise, make MU responsible for all the symbols.
918 auto UMI = std::make_shared<UnmaterializedInfo>(std::move(MU));
919 for (auto &KV : UMI->MU->getSymbols()) {
920 auto SymI = Symbols.find(KV.first);
921 assert(SymI->second.getState() == SymbolState::Materializing &&((SymI->second.getState() == SymbolState::Materializing &&
"Can not replace a symbol that is not materializing") ? static_cast
<void> (0) : __assert_fail ("SymI->second.getState() == SymbolState::Materializing && \"Can not replace a symbol that is not materializing\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 922, __PRETTY_FUNCTION__))
922 "Can not replace a symbol that is not materializing")((SymI->second.getState() == SymbolState::Materializing &&
"Can not replace a symbol that is not materializing") ? static_cast
<void> (0) : __assert_fail ("SymI->second.getState() == SymbolState::Materializing && \"Can not replace a symbol that is not materializing\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 922, __PRETTY_FUNCTION__))
;
923 assert(!SymI->second.hasMaterializerAttached() &&((!SymI->second.hasMaterializerAttached() && "Can not replace a symbol that has a materializer attached"
) ? static_cast<void> (0) : __assert_fail ("!SymI->second.hasMaterializerAttached() && \"Can not replace a symbol that has a materializer attached\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 924, __PRETTY_FUNCTION__))
924 "Can not replace a symbol that has a materializer attached")((!SymI->second.hasMaterializerAttached() && "Can not replace a symbol that has a materializer attached"
) ? static_cast<void> (0) : __assert_fail ("!SymI->second.hasMaterializerAttached() && \"Can not replace a symbol that has a materializer attached\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 924, __PRETTY_FUNCTION__))
;
925 assert(UnmaterializedInfos.count(KV.first) == 0 &&((UnmaterializedInfos.count(KV.first) == 0 && "Unexpected materializer entry in map"
) ? static_cast<void> (0) : __assert_fail ("UnmaterializedInfos.count(KV.first) == 0 && \"Unexpected materializer entry in map\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 926, __PRETTY_FUNCTION__))
926 "Unexpected materializer entry in map")((UnmaterializedInfos.count(KV.first) == 0 && "Unexpected materializer entry in map"
) ? static_cast<void> (0) : __assert_fail ("UnmaterializedInfos.count(KV.first) == 0 && \"Unexpected materializer entry in map\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 926, __PRETTY_FUNCTION__))
;
927 SymI->second.setAddress(SymI->second.getAddress());
928 SymI->second.setMaterializerAttached(true);
929 UnmaterializedInfos[KV.first] = UMI;
930 }
931
932 return nullptr;
933 });
934
935 if (MustRunMU)
936 ES.dispatchMaterialization(*this, std::move(MustRunMU));
937}
938
939SymbolNameSet
940JITDylib::getRequestedSymbols(const SymbolFlagsMap &SymbolFlags) const {
941 return ES.runSessionLocked([&]() {
942 SymbolNameSet RequestedSymbols;
943
944 for (auto &KV : SymbolFlags) {
945 assert(Symbols.count(KV.first) && "JITDylib does not cover this symbol?")((Symbols.count(KV.first) && "JITDylib does not cover this symbol?"
) ? static_cast<void> (0) : __assert_fail ("Symbols.count(KV.first) && \"JITDylib does not cover this symbol?\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 945, __PRETTY_FUNCTION__))
;
946 assert(Symbols.find(KV.first)->second.getState() !=((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") ? static_cast<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-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 950, __PRETTY_FUNCTION__))
947 SymbolState::NeverSearched &&((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") ? static_cast<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-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 950, __PRETTY_FUNCTION__))
948 Symbols.find(KV.first)->second.getState() != SymbolState::Ready &&((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") ? static_cast<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-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 950, __PRETTY_FUNCTION__))
949 "getRequestedSymbols can only be called for symbols that have "((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") ? static_cast<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-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 950, __PRETTY_FUNCTION__))
950 "started materializing")((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") ? static_cast<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-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 950, __PRETTY_FUNCTION__))
;
951 auto I = MaterializingInfos.find(KV.first);
952 if (I == MaterializingInfos.end())
953 continue;
954
955 if (I->second.hasQueriesPending())
956 RequestedSymbols.insert(KV.first);
957 }
958
959 return RequestedSymbols;
960 });
961}
962
963void JITDylib::addDependencies(const SymbolStringPtr &Name,
964 const SymbolDependenceMap &Dependencies) {
965 assert(Symbols.count(Name) && "Name not in symbol table")((Symbols.count(Name) && "Name not in symbol table") ?
static_cast<void> (0) : __assert_fail ("Symbols.count(Name) && \"Name not in symbol table\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 965, __PRETTY_FUNCTION__))
;
966 assert(Symbols[Name].getState() < SymbolState::Emitted &&((Symbols[Name].getState() < SymbolState::Emitted &&
"Can not add dependencies for a symbol that is not materializing"
) ? static_cast<void> (0) : __assert_fail ("Symbols[Name].getState() < SymbolState::Emitted && \"Can not add dependencies for a symbol that is not materializing\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 967, __PRETTY_FUNCTION__))
967 "Can not add dependencies for a symbol that is not materializing")((Symbols[Name].getState() < SymbolState::Emitted &&
"Can not add dependencies for a symbol that is not materializing"
) ? static_cast<void> (0) : __assert_fail ("Symbols[Name].getState() < SymbolState::Emitted && \"Can not add dependencies for a symbol that is not materializing\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 967, __PRETTY_FUNCTION__))
;
968
969 LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { dbgs() << "In " << getName() <<
" adding dependencies for " << *Name << ": " <<
Dependencies << "\n"; }; } } while (false)
970 dbgs() << "In " << getName() << " adding dependencies for "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { dbgs() << "In " << getName() <<
" adding dependencies for " << *Name << ": " <<
Dependencies << "\n"; }; } } while (false)
971 << *Name << ": " << Dependencies << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { dbgs() << "In " << getName() <<
" adding dependencies for " << *Name << ": " <<
Dependencies << "\n"; }; } } while (false)
972 })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { dbgs() << "In " << getName() <<
" adding dependencies for " << *Name << ": " <<
Dependencies << "\n"; }; } } while (false)
;
973
974 // If Name is already in an error state then just bail out.
975 if (Symbols[Name].getFlags().hasError())
976 return;
977
978 auto &MI = MaterializingInfos[Name];
979 assert(Symbols[Name].getState() != SymbolState::Emitted &&((Symbols[Name].getState() != SymbolState::Emitted &&
"Can not add dependencies to an emitted symbol") ? static_cast
<void> (0) : __assert_fail ("Symbols[Name].getState() != SymbolState::Emitted && \"Can not add dependencies to an emitted symbol\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 980, __PRETTY_FUNCTION__))
980 "Can not add dependencies to an emitted symbol")((Symbols[Name].getState() != SymbolState::Emitted &&
"Can not add dependencies to an emitted symbol") ? static_cast
<void> (0) : __assert_fail ("Symbols[Name].getState() != SymbolState::Emitted && \"Can not add dependencies to an emitted symbol\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 980, __PRETTY_FUNCTION__))
;
981
982 bool DependsOnSymbolInErrorState = false;
983
984 // Register dependencies, record whether any depenendency is in the error
985 // state.
986 for (auto &KV : Dependencies) {
987 assert(KV.first && "Null JITDylib in dependency?")((KV.first && "Null JITDylib in dependency?") ? static_cast
<void> (0) : __assert_fail ("KV.first && \"Null JITDylib in dependency?\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 987, __PRETTY_FUNCTION__))
;
988 auto &OtherJITDylib = *KV.first;
989 auto &DepsOnOtherJITDylib = MI.UnemittedDependencies[&OtherJITDylib];
990
991 for (auto &OtherSymbol : KV.second) {
992
993 // Check the sym entry for the dependency.
994 auto OtherSymI = OtherJITDylib.Symbols.find(OtherSymbol);
995
996#ifndef NDEBUG
997 // Assert that this symbol exists and has not reached the ready state
998 // already.
999 assert(OtherSymI != OtherJITDylib.Symbols.end() &&((OtherSymI != OtherJITDylib.Symbols.end() && (OtherSymI
->second.getState() < SymbolState::Ready && "Dependency on emitted/ready symbol"
)) ? static_cast<void> (0) : __assert_fail ("OtherSymI != OtherJITDylib.Symbols.end() && (OtherSymI->second.getState() < SymbolState::Ready && \"Dependency on emitted/ready symbol\")"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1001, __PRETTY_FUNCTION__))
1000 (OtherSymI->second.getState() < SymbolState::Ready &&((OtherSymI != OtherJITDylib.Symbols.end() && (OtherSymI
->second.getState() < SymbolState::Ready && "Dependency on emitted/ready symbol"
)) ? static_cast<void> (0) : __assert_fail ("OtherSymI != OtherJITDylib.Symbols.end() && (OtherSymI->second.getState() < SymbolState::Ready && \"Dependency on emitted/ready symbol\")"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1001, __PRETTY_FUNCTION__))
1001 "Dependency on emitted/ready symbol"))((OtherSymI != OtherJITDylib.Symbols.end() && (OtherSymI
->second.getState() < SymbolState::Ready && "Dependency on emitted/ready symbol"
)) ? static_cast<void> (0) : __assert_fail ("OtherSymI != OtherJITDylib.Symbols.end() && (OtherSymI->second.getState() < SymbolState::Ready && \"Dependency on emitted/ready symbol\")"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1001, __PRETTY_FUNCTION__))
;
1002#endif
1003
1004 auto &OtherSymEntry = OtherSymI->second;
1005
1006 // If the dependency is in an error state then note this and continue,
1007 // we will move this symbol to the error state below.
1008 if (OtherSymEntry.getFlags().hasError()) {
1009 DependsOnSymbolInErrorState = true;
1010 continue;
1011 }
1012
1013 // If the dependency was not in the error state then add it to
1014 // our list of dependencies.
1015 assert(OtherJITDylib.MaterializingInfos.count(OtherSymbol) &&((OtherJITDylib.MaterializingInfos.count(OtherSymbol) &&
"No MaterializingInfo for dependency") ? static_cast<void
> (0) : __assert_fail ("OtherJITDylib.MaterializingInfos.count(OtherSymbol) && \"No MaterializingInfo for dependency\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1016, __PRETTY_FUNCTION__))
1016 "No MaterializingInfo for dependency")((OtherJITDylib.MaterializingInfos.count(OtherSymbol) &&
"No MaterializingInfo for dependency") ? static_cast<void
> (0) : __assert_fail ("OtherJITDylib.MaterializingInfos.count(OtherSymbol) && \"No MaterializingInfo for dependency\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1016, __PRETTY_FUNCTION__))
;
1017 auto &OtherMI = OtherJITDylib.MaterializingInfos[OtherSymbol];
1018
1019 if (OtherSymEntry.getState() == SymbolState::Emitted)
1020 transferEmittedNodeDependencies(MI, Name, OtherMI);
1021 else if (&OtherJITDylib != this || OtherSymbol != Name) {
1022 OtherMI.Dependants[this].insert(Name);
1023 DepsOnOtherJITDylib.insert(OtherSymbol);
1024 }
1025 }
1026
1027 if (DepsOnOtherJITDylib.empty())
1028 MI.UnemittedDependencies.erase(&OtherJITDylib);
1029 }
1030
1031 // If this symbol dependended on any symbols in the error state then move
1032 // this symbol to the error state too.
1033 if (DependsOnSymbolInErrorState)
1034 Symbols[Name].setFlags(Symbols[Name].getFlags() | JITSymbolFlags::HasError);
1035}
1036
1037Error JITDylib::resolve(const SymbolMap &Resolved) {
1038 SymbolNameSet SymbolsInErrorState;
1039 AsynchronousSymbolQuerySet CompletedQueries;
1040
1041 ES.runSessionLocked([&, this]() {
1042 struct WorklistEntry {
1043 SymbolTable::iterator SymI;
1044 JITEvaluatedSymbol ResolvedSym;
1045 };
1046
1047 std::vector<WorklistEntry> Worklist;
1048 Worklist.reserve(Resolved.size());
1049
1050 // Build worklist and check for any symbols in the error state.
1051 for (const auto &KV : Resolved) {
1052
1053 assert(!KV.second.getFlags().hasError() &&((!KV.second.getFlags().hasError() && "Resolution result can not have error flag set"
) ? static_cast<void> (0) : __assert_fail ("!KV.second.getFlags().hasError() && \"Resolution result can not have error flag set\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1054, __PRETTY_FUNCTION__))
1054 "Resolution result can not have error flag set")((!KV.second.getFlags().hasError() && "Resolution result can not have error flag set"
) ? static_cast<void> (0) : __assert_fail ("!KV.second.getFlags().hasError() && \"Resolution result can not have error flag set\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1054, __PRETTY_FUNCTION__))
;
1055
1056 auto SymI = Symbols.find(KV.first);
1057
1058 assert(SymI != Symbols.end() && "Symbol not found")((SymI != Symbols.end() && "Symbol not found") ? static_cast
<void> (0) : __assert_fail ("SymI != Symbols.end() && \"Symbol not found\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1058, __PRETTY_FUNCTION__))
;
1059 assert(!SymI->second.hasMaterializerAttached() &&((!SymI->second.hasMaterializerAttached() && "Resolving symbol with materializer attached?"
) ? static_cast<void> (0) : __assert_fail ("!SymI->second.hasMaterializerAttached() && \"Resolving symbol with materializer attached?\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1060, __PRETTY_FUNCTION__))
1060 "Resolving symbol with materializer attached?")((!SymI->second.hasMaterializerAttached() && "Resolving symbol with materializer attached?"
) ? static_cast<void> (0) : __assert_fail ("!SymI->second.hasMaterializerAttached() && \"Resolving symbol with materializer attached?\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1060, __PRETTY_FUNCTION__))
;
1061 assert(SymI->second.getState() == SymbolState::Materializing &&((SymI->second.getState() == SymbolState::Materializing &&
"Symbol should be materializing") ? static_cast<void> (
0) : __assert_fail ("SymI->second.getState() == SymbolState::Materializing && \"Symbol should be materializing\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1062, __PRETTY_FUNCTION__))
1062 "Symbol should be materializing")((SymI->second.getState() == SymbolState::Materializing &&
"Symbol should be materializing") ? static_cast<void> (
0) : __assert_fail ("SymI->second.getState() == SymbolState::Materializing && \"Symbol should be materializing\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1062, __PRETTY_FUNCTION__))
;
1063 assert(SymI->second.getAddress() == 0 &&((SymI->second.getAddress() == 0 && "Symbol has already been resolved"
) ? static_cast<void> (0) : __assert_fail ("SymI->second.getAddress() == 0 && \"Symbol has already been resolved\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1064, __PRETTY_FUNCTION__))
1064 "Symbol has already been resolved")((SymI->second.getAddress() == 0 && "Symbol has already been resolved"
) ? static_cast<void> (0) : __assert_fail ("SymI->second.getAddress() == 0 && \"Symbol has already been resolved\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1064, __PRETTY_FUNCTION__))
;
1065
1066 if (SymI->second.getFlags().hasError())
1067 SymbolsInErrorState.insert(KV.first);
1068 else {
1069 auto Flags = KV.second.getFlags();
1070 Flags &= ~(JITSymbolFlags::Weak | JITSymbolFlags::Common);
1071 assert(Flags == (SymI->second.getFlags() &((Flags == (SymI->second.getFlags() & ~(JITSymbolFlags
::Weak | JITSymbolFlags::Common)) && "Resolved flags should match the declared flags"
) ? static_cast<void> (0) : __assert_fail ("Flags == (SymI->second.getFlags() & ~(JITSymbolFlags::Weak | JITSymbolFlags::Common)) && \"Resolved flags should match the declared flags\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1073, __PRETTY_FUNCTION__))
1072 ~(JITSymbolFlags::Weak | JITSymbolFlags::Common)) &&((Flags == (SymI->second.getFlags() & ~(JITSymbolFlags
::Weak | JITSymbolFlags::Common)) && "Resolved flags should match the declared flags"
) ? static_cast<void> (0) : __assert_fail ("Flags == (SymI->second.getFlags() & ~(JITSymbolFlags::Weak | JITSymbolFlags::Common)) && \"Resolved flags should match the declared flags\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1073, __PRETTY_FUNCTION__))
1073 "Resolved flags should match the declared flags")((Flags == (SymI->second.getFlags() & ~(JITSymbolFlags
::Weak | JITSymbolFlags::Common)) && "Resolved flags should match the declared flags"
) ? static_cast<void> (0) : __assert_fail ("Flags == (SymI->second.getFlags() & ~(JITSymbolFlags::Weak | JITSymbolFlags::Common)) && \"Resolved flags should match the declared flags\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1073, __PRETTY_FUNCTION__))
;
1074
1075 Worklist.push_back(
1076 {SymI, JITEvaluatedSymbol(KV.second.getAddress(), Flags)});
1077 }
1078 }
1079
1080 // If any symbols were in the error state then bail out.
1081 if (!SymbolsInErrorState.empty())
1082 return;
1083
1084 while (!Worklist.empty()) {
1085 auto SymI = Worklist.back().SymI;
1086 auto ResolvedSym = Worklist.back().ResolvedSym;
1087 Worklist.pop_back();
1088
1089 auto &Name = SymI->first;
1090
1091 // Resolved symbols can not be weak: discard the weak flag.
1092 JITSymbolFlags ResolvedFlags = ResolvedSym.getFlags();
1093 SymI->second.setAddress(ResolvedSym.getAddress());
1094 SymI->second.setFlags(ResolvedFlags);
1095 SymI->second.setState(SymbolState::Resolved);
1096
1097 auto &MI = MaterializingInfos[Name];
1098 for (auto &Q : MI.takeQueriesMeeting(SymbolState::Resolved)) {
1099 Q->notifySymbolMetRequiredState(Name, ResolvedSym);
1100 Q->removeQueryDependence(*this, Name);
1101 if (Q->isComplete())
1102 CompletedQueries.insert(std::move(Q));
1103 }
1104 }
1105 });
1106
1107 assert((SymbolsInErrorState.empty() || CompletedQueries.empty()) &&(((SymbolsInErrorState.empty() || CompletedQueries.empty()) &&
"Can't fail symbols and completed queries at the same time")
? static_cast<void> (0) : __assert_fail ("(SymbolsInErrorState.empty() || CompletedQueries.empty()) && \"Can't fail symbols and completed queries at the same time\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1108, __PRETTY_FUNCTION__))
1108 "Can't fail symbols and completed queries at the same time")(((SymbolsInErrorState.empty() || CompletedQueries.empty()) &&
"Can't fail symbols and completed queries at the same time")
? static_cast<void> (0) : __assert_fail ("(SymbolsInErrorState.empty() || CompletedQueries.empty()) && \"Can't fail symbols and completed queries at the same time\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1108, __PRETTY_FUNCTION__))
;
1109
1110 // If we failed any symbols then return an error.
1111 if (!SymbolsInErrorState.empty()) {
1112 auto FailedSymbolsDepMap = std::make_shared<SymbolDependenceMap>();
1113 (*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState);
1114 return make_error<FailedToMaterialize>(std::move(FailedSymbolsDepMap));
1115 }
1116
1117 // Otherwise notify all the completed queries.
1118 for (auto &Q : CompletedQueries) {
1119 assert(Q->isComplete() && "Q not completed")((Q->isComplete() && "Q not completed") ? static_cast
<void> (0) : __assert_fail ("Q->isComplete() && \"Q not completed\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1119, __PRETTY_FUNCTION__))
;
1120 Q->handleComplete();
1121 }
1122
1123 return Error::success();
1124}
1125
1126Error JITDylib::emit(const SymbolFlagsMap &Emitted) {
1127 AsynchronousSymbolQuerySet CompletedQueries;
1128 SymbolNameSet SymbolsInErrorState;
1129 DenseMap<JITDylib *, SymbolNameVector> ReadySymbols;
1130
1131 ES.runSessionLocked([&, this]() {
1132 std::vector<SymbolTable::iterator> Worklist;
1133
1134 // Scan to build worklist, record any symbols in the erorr state.
1135 for (const auto &KV : Emitted) {
1136 auto &Name = KV.first;
1137
1138 auto SymI = Symbols.find(Name);
1139 assert(SymI != Symbols.end() && "No symbol table entry for Name")((SymI != Symbols.end() && "No symbol table entry for Name"
) ? static_cast<void> (0) : __assert_fail ("SymI != Symbols.end() && \"No symbol table entry for Name\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1139, __PRETTY_FUNCTION__))
;
1140
1141 if (SymI->second.getFlags().hasError())
1142 SymbolsInErrorState.insert(Name);
1143 else
1144 Worklist.push_back(SymI);
1145 }
1146
1147 // If any symbols were in the error state then bail out.
1148 if (!SymbolsInErrorState.empty())
1149 return;
1150
1151 // Otherwise update dependencies and move to the emitted state.
1152 while (!Worklist.empty()) {
1153 auto SymI = Worklist.back();
1154 Worklist.pop_back();
1155
1156 auto &Name = SymI->first;
1157 auto &SymEntry = SymI->second;
1158
1159 // Move symbol to the emitted state.
1160 assert(SymEntry.getState() == SymbolState::Resolved &&((SymEntry.getState() == SymbolState::Resolved && "Emitting from state other than Resolved"
) ? static_cast<void> (0) : __assert_fail ("SymEntry.getState() == SymbolState::Resolved && \"Emitting from state other than Resolved\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1161, __PRETTY_FUNCTION__))
1161 "Emitting from state other than Resolved")((SymEntry.getState() == SymbolState::Resolved && "Emitting from state other than Resolved"
) ? static_cast<void> (0) : __assert_fail ("SymEntry.getState() == SymbolState::Resolved && \"Emitting from state other than Resolved\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1161, __PRETTY_FUNCTION__))
;
1162 SymEntry.setState(SymbolState::Emitted);
1163
1164 auto MII = MaterializingInfos.find(Name);
1165 assert(MII != MaterializingInfos.end() &&((MII != MaterializingInfos.end() && "Missing MaterializingInfo entry"
) ? static_cast<void> (0) : __assert_fail ("MII != MaterializingInfos.end() && \"Missing MaterializingInfo entry\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1166, __PRETTY_FUNCTION__))
1166 "Missing MaterializingInfo entry")((MII != MaterializingInfos.end() && "Missing MaterializingInfo entry"
) ? static_cast<void> (0) : __assert_fail ("MII != MaterializingInfos.end() && \"Missing MaterializingInfo entry\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1166, __PRETTY_FUNCTION__))
;
1167 auto &MI = MII->second;
1168
1169 // For each dependant, transfer this node's emitted dependencies to
1170 // it. If the dependant node is ready (i.e. has no unemitted
1171 // dependencies) then notify any pending queries.
1172 for (auto &KV : MI.Dependants) {
1173 auto &DependantJD = *KV.first;
1174 auto &DependantJDReadySymbols = ReadySymbols[&DependantJD];
1175 for (auto &DependantName : KV.second) {
1176 auto DependantMII =
1177 DependantJD.MaterializingInfos.find(DependantName);
1178 assert(DependantMII != DependantJD.MaterializingInfos.end() &&((DependantMII != DependantJD.MaterializingInfos.end() &&
"Dependant should have MaterializingInfo") ? static_cast<
void> (0) : __assert_fail ("DependantMII != DependantJD.MaterializingInfos.end() && \"Dependant should have MaterializingInfo\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1179, __PRETTY_FUNCTION__))
1179 "Dependant should have MaterializingInfo")((DependantMII != DependantJD.MaterializingInfos.end() &&
"Dependant should have MaterializingInfo") ? static_cast<
void> (0) : __assert_fail ("DependantMII != DependantJD.MaterializingInfos.end() && \"Dependant should have MaterializingInfo\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1179, __PRETTY_FUNCTION__))
;
1180
1181 auto &DependantMI = DependantMII->second;
1182
1183 // Remove the dependant's dependency on this node.
1184 assert(DependantMI.UnemittedDependencies.count(this) &&((DependantMI.UnemittedDependencies.count(this) && "Dependant does not have an unemitted dependencies record for "
"this JITDylib") ? static_cast<void> (0) : __assert_fail
("DependantMI.UnemittedDependencies.count(this) && \"Dependant does not have an unemitted dependencies record for \" \"this JITDylib\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1186, __PRETTY_FUNCTION__))
1185 "Dependant does not have an unemitted dependencies record for "((DependantMI.UnemittedDependencies.count(this) && "Dependant does not have an unemitted dependencies record for "
"this JITDylib") ? static_cast<void> (0) : __assert_fail
("DependantMI.UnemittedDependencies.count(this) && \"Dependant does not have an unemitted dependencies record for \" \"this JITDylib\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1186, __PRETTY_FUNCTION__))
1186 "this JITDylib")((DependantMI.UnemittedDependencies.count(this) && "Dependant does not have an unemitted dependencies record for "
"this JITDylib") ? static_cast<void> (0) : __assert_fail
("DependantMI.UnemittedDependencies.count(this) && \"Dependant does not have an unemitted dependencies record for \" \"this JITDylib\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1186, __PRETTY_FUNCTION__))
;
1187 assert(DependantMI.UnemittedDependencies[this].count(Name) &&((DependantMI.UnemittedDependencies[this].count(Name) &&
"Dependant does not count this symbol as a dependency?") ? static_cast
<void> (0) : __assert_fail ("DependantMI.UnemittedDependencies[this].count(Name) && \"Dependant does not count this symbol as a dependency?\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1188, __PRETTY_FUNCTION__))
1188 "Dependant does not count this symbol as a dependency?")((DependantMI.UnemittedDependencies[this].count(Name) &&
"Dependant does not count this symbol as a dependency?") ? static_cast
<void> (0) : __assert_fail ("DependantMI.UnemittedDependencies[this].count(Name) && \"Dependant does not count this symbol as a dependency?\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1188, __PRETTY_FUNCTION__))
;
1189
1190 DependantMI.UnemittedDependencies[this].erase(Name);
1191 if (DependantMI.UnemittedDependencies[this].empty())
1192 DependantMI.UnemittedDependencies.erase(this);
1193
1194 // Transfer unemitted dependencies from this node to the dependant.
1195 DependantJD.transferEmittedNodeDependencies(DependantMI,
1196 DependantName, MI);
1197
1198 auto DependantSymI = DependantJD.Symbols.find(DependantName);
1199 assert(DependantSymI != DependantJD.Symbols.end() &&((DependantSymI != DependantJD.Symbols.end() && "Dependant has no entry in the Symbols table"
) ? static_cast<void> (0) : __assert_fail ("DependantSymI != DependantJD.Symbols.end() && \"Dependant has no entry in the Symbols table\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1200, __PRETTY_FUNCTION__))
1200 "Dependant has no entry in the Symbols table")((DependantSymI != DependantJD.Symbols.end() && "Dependant has no entry in the Symbols table"
) ? static_cast<void> (0) : __assert_fail ("DependantSymI != DependantJD.Symbols.end() && \"Dependant has no entry in the Symbols table\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1200, __PRETTY_FUNCTION__))
;
1201 auto &DependantSymEntry = DependantSymI->second;
1202
1203 // If the dependant is emitted and this node was the last of its
1204 // unemitted dependencies then the dependant node is now ready, so
1205 // notify any pending queries on the dependant node.
1206 if (DependantSymEntry.getState() == SymbolState::Emitted &&
1207 DependantMI.UnemittedDependencies.empty()) {
1208 assert(DependantMI.Dependants.empty() &&((DependantMI.Dependants.empty() && "Dependants should be empty by now"
) ? static_cast<void> (0) : __assert_fail ("DependantMI.Dependants.empty() && \"Dependants should be empty by now\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1209, __PRETTY_FUNCTION__))
1209 "Dependants should be empty by now")((DependantMI.Dependants.empty() && "Dependants should be empty by now"
) ? static_cast<void> (0) : __assert_fail ("DependantMI.Dependants.empty() && \"Dependants should be empty by now\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1209, __PRETTY_FUNCTION__))
;
1210
1211 // Since this dependant is now ready, we erase its MaterializingInfo
1212 // and update its materializing state.
1213 DependantSymEntry.setState(SymbolState::Ready);
1214 DependantJDReadySymbols.push_back(DependantName);
1215
1216 for (auto &Q : DependantMI.takeQueriesMeeting(SymbolState::Ready)) {
1217 Q->notifySymbolMetRequiredState(
1218 DependantName, DependantSymI->second.getSymbol());
1219 if (Q->isComplete())
1220 CompletedQueries.insert(Q);
1221 Q->removeQueryDependence(DependantJD, DependantName);
1222 }
1223 }
1224 }
1225 }
1226
1227 auto &ThisJDReadySymbols = ReadySymbols[this];
1228 MI.Dependants.clear();
1229 if (MI.UnemittedDependencies.empty()) {
1230 SymI->second.setState(SymbolState::Ready);
1231 ThisJDReadySymbols.push_back(Name);
1232 for (auto &Q : MI.takeQueriesMeeting(SymbolState::Ready)) {
1233 Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
1234 if (Q->isComplete())
1235 CompletedQueries.insert(Q);
1236 Q->removeQueryDependence(*this, Name);
1237 }
1238 }
1239 }
1240 });
1241
1242 assert((SymbolsInErrorState.empty() || CompletedQueries.empty()) &&(((SymbolsInErrorState.empty() || CompletedQueries.empty()) &&
"Can't fail symbols and completed queries at the same time")
? static_cast<void> (0) : __assert_fail ("(SymbolsInErrorState.empty() || CompletedQueries.empty()) && \"Can't fail symbols and completed queries at the same time\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1243, __PRETTY_FUNCTION__))
1243 "Can't fail symbols and completed queries at the same time")(((SymbolsInErrorState.empty() || CompletedQueries.empty()) &&
"Can't fail symbols and completed queries at the same time")
? static_cast<void> (0) : __assert_fail ("(SymbolsInErrorState.empty() || CompletedQueries.empty()) && \"Can't fail symbols and completed queries at the same time\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1243, __PRETTY_FUNCTION__))
;
1244
1245 // If we failed any symbols then return an error.
1246 if (!SymbolsInErrorState.empty()) {
1247 auto FailedSymbolsDepMap = std::make_shared<SymbolDependenceMap>();
1248 (*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState);
1249 return make_error<FailedToMaterialize>(std::move(FailedSymbolsDepMap));
1250 }
1251
1252 // Otherwise notify all the completed queries.
1253 for (auto &Q : CompletedQueries) {
1254 assert(Q->isComplete() && "Q is not complete")((Q->isComplete() && "Q is not complete") ? static_cast
<void> (0) : __assert_fail ("Q->isComplete() && \"Q is not complete\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1254, __PRETTY_FUNCTION__))
;
1255 Q->handleComplete();
1256 }
1257
1258 return Error::success();
1259}
1260
1261void JITDylib::notifyFailed(FailedSymbolsWorklist Worklist) {
1262 AsynchronousSymbolQuerySet FailedQueries;
1263 auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
1264
1265 // Failing no symbols is a no-op.
1266 if (Worklist.empty())
1267 return;
1268
1269 auto &ES = Worklist.front().first->getExecutionSession();
1270
1271 ES.runSessionLocked([&]() {
1272 while (!Worklist.empty()) {
1273 assert(Worklist.back().first && "Failed JITDylib can not be null")((Worklist.back().first && "Failed JITDylib can not be null"
) ? static_cast<void> (0) : __assert_fail ("Worklist.back().first && \"Failed JITDylib can not be null\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1273, __PRETTY_FUNCTION__))
;
1274 auto &JD = *Worklist.back().first;
1275 auto Name = std::move(Worklist.back().second);
1276 Worklist.pop_back();
1277
1278 (*FailedSymbolsMap)[&JD].insert(Name);
1279
1280 assert(JD.Symbols.count(Name) && "No symbol table entry for Name")((JD.Symbols.count(Name) && "No symbol table entry for Name"
) ? static_cast<void> (0) : __assert_fail ("JD.Symbols.count(Name) && \"No symbol table entry for Name\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1280, __PRETTY_FUNCTION__))
;
1281 auto &Sym = JD.Symbols[Name];
1282
1283 // Move the symbol into the error state.
1284 // Note that this may be redundant: The symbol might already have been
1285 // moved to this state in response to the failure of a dependence.
1286 Sym.setFlags(Sym.getFlags() | JITSymbolFlags::HasError);
1287
1288 // FIXME: Come up with a sane mapping of state to
1289 // presence-of-MaterializingInfo so that we can assert presence / absence
1290 // here, rather than testing it.
1291 auto MII = JD.MaterializingInfos.find(Name);
1292
1293 if (MII == JD.MaterializingInfos.end())
1294 continue;
1295
1296 auto &MI = MII->second;
1297
1298 // Move all dependants to the error state and disconnect from them.
1299 for (auto &KV : MI.Dependants) {
1300 auto &DependantJD = *KV.first;
1301 for (auto &DependantName : KV.second) {
1302 assert(DependantJD.Symbols.count(DependantName) &&((DependantJD.Symbols.count(DependantName) && "No symbol table entry for DependantName"
) ? static_cast<void> (0) : __assert_fail ("DependantJD.Symbols.count(DependantName) && \"No symbol table entry for DependantName\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1303, __PRETTY_FUNCTION__))
1303 "No symbol table entry for DependantName")((DependantJD.Symbols.count(DependantName) && "No symbol table entry for DependantName"
) ? static_cast<void> (0) : __assert_fail ("DependantJD.Symbols.count(DependantName) && \"No symbol table entry for DependantName\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1303, __PRETTY_FUNCTION__))
;
1304 auto &DependantSym = DependantJD.Symbols[DependantName];
1305 DependantSym.setFlags(DependantSym.getFlags() |
1306 JITSymbolFlags::HasError);
1307
1308 assert(DependantJD.MaterializingInfos.count(DependantName) &&((DependantJD.MaterializingInfos.count(DependantName) &&
"No MaterializingInfo for dependant") ? static_cast<void>
(0) : __assert_fail ("DependantJD.MaterializingInfos.count(DependantName) && \"No MaterializingInfo for dependant\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1309, __PRETTY_FUNCTION__))
1309 "No MaterializingInfo for dependant")((DependantJD.MaterializingInfos.count(DependantName) &&
"No MaterializingInfo for dependant") ? static_cast<void>
(0) : __assert_fail ("DependantJD.MaterializingInfos.count(DependantName) && \"No MaterializingInfo for dependant\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1309, __PRETTY_FUNCTION__))
;
1310 auto &DependantMI = DependantJD.MaterializingInfos[DependantName];
1311
1312 auto UnemittedDepI = DependantMI.UnemittedDependencies.find(&JD);
1313 assert(UnemittedDepI != DependantMI.UnemittedDependencies.end() &&((UnemittedDepI != DependantMI.UnemittedDependencies.end() &&
"No UnemittedDependencies entry for this JITDylib") ? static_cast
<void> (0) : __assert_fail ("UnemittedDepI != DependantMI.UnemittedDependencies.end() && \"No UnemittedDependencies entry for this JITDylib\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1314, __PRETTY_FUNCTION__))
1314 "No UnemittedDependencies entry for this JITDylib")((UnemittedDepI != DependantMI.UnemittedDependencies.end() &&
"No UnemittedDependencies entry for this JITDylib") ? static_cast
<void> (0) : __assert_fail ("UnemittedDepI != DependantMI.UnemittedDependencies.end() && \"No UnemittedDependencies entry for this JITDylib\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1314, __PRETTY_FUNCTION__))
;
1315 assert(UnemittedDepI->second.count(Name) &&((UnemittedDepI->second.count(Name) && "No UnemittedDependencies entry for this symbol"
) ? static_cast<void> (0) : __assert_fail ("UnemittedDepI->second.count(Name) && \"No UnemittedDependencies entry for this symbol\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1316, __PRETTY_FUNCTION__))
1316 "No UnemittedDependencies entry for this symbol")((UnemittedDepI->second.count(Name) && "No UnemittedDependencies entry for this symbol"
) ? static_cast<void> (0) : __assert_fail ("UnemittedDepI->second.count(Name) && \"No UnemittedDependencies entry for this symbol\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1316, __PRETTY_FUNCTION__))
;
1317 UnemittedDepI->second.erase(Name);
1318 if (UnemittedDepI->second.empty())
1319 DependantMI.UnemittedDependencies.erase(UnemittedDepI);
1320
1321 // If this symbol is already in the emitted state then we need to
1322 // take responsibility for failing its queries, so add it to the
1323 // worklist.
1324 if (DependantSym.getState() == SymbolState::Emitted) {
1325 assert(DependantMI.Dependants.empty() &&((DependantMI.Dependants.empty() && "Emitted symbol should not have dependants"
) ? static_cast<void> (0) : __assert_fail ("DependantMI.Dependants.empty() && \"Emitted symbol should not have dependants\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1326, __PRETTY_FUNCTION__))
1326 "Emitted symbol should not have dependants")((DependantMI.Dependants.empty() && "Emitted symbol should not have dependants"
) ? static_cast<void> (0) : __assert_fail ("DependantMI.Dependants.empty() && \"Emitted symbol should not have dependants\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1326, __PRETTY_FUNCTION__))
;
1327 Worklist.push_back(std::make_pair(&DependantJD, DependantName));
1328 }
1329 }
1330 }
1331 MI.Dependants.clear();
1332
1333 // Disconnect from all unemitted depenencies.
1334 for (auto &KV : MI.UnemittedDependencies) {
1335 auto &UnemittedDepJD = *KV.first;
1336 for (auto &UnemittedDepName : KV.second) {
1337 auto UnemittedDepMII =
1338 UnemittedDepJD.MaterializingInfos.find(UnemittedDepName);
1339 assert(UnemittedDepMII != UnemittedDepJD.MaterializingInfos.end() &&((UnemittedDepMII != UnemittedDepJD.MaterializingInfos.end() &&
"Missing MII for unemitted dependency") ? static_cast<void
> (0) : __assert_fail ("UnemittedDepMII != UnemittedDepJD.MaterializingInfos.end() && \"Missing MII for unemitted dependency\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1340, __PRETTY_FUNCTION__))
1340 "Missing MII for unemitted dependency")((UnemittedDepMII != UnemittedDepJD.MaterializingInfos.end() &&
"Missing MII for unemitted dependency") ? static_cast<void
> (0) : __assert_fail ("UnemittedDepMII != UnemittedDepJD.MaterializingInfos.end() && \"Missing MII for unemitted dependency\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1340, __PRETTY_FUNCTION__))
;
1341 assert(UnemittedDepMII->second.Dependants.count(&JD) &&((UnemittedDepMII->second.Dependants.count(&JD) &&
"JD not listed as a dependant of unemitted dependency") ? static_cast
<void> (0) : __assert_fail ("UnemittedDepMII->second.Dependants.count(&JD) && \"JD not listed as a dependant of unemitted dependency\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1342, __PRETTY_FUNCTION__))
1342 "JD not listed as a dependant of unemitted dependency")((UnemittedDepMII->second.Dependants.count(&JD) &&
"JD not listed as a dependant of unemitted dependency") ? static_cast
<void> (0) : __assert_fail ("UnemittedDepMII->second.Dependants.count(&JD) && \"JD not listed as a dependant of unemitted dependency\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1342, __PRETTY_FUNCTION__))
;
1343 assert(UnemittedDepMII->second.Dependants[&JD].count(Name) &&((UnemittedDepMII->second.Dependants[&JD].count(Name) &&
"Name is not listed as a dependant of unemitted dependency")
? static_cast<void> (0) : __assert_fail ("UnemittedDepMII->second.Dependants[&JD].count(Name) && \"Name is not listed as a dependant of unemitted dependency\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1344, __PRETTY_FUNCTION__))
1344 "Name is not listed as a dependant of unemitted dependency")((UnemittedDepMII->second.Dependants[&JD].count(Name) &&
"Name is not listed as a dependant of unemitted dependency")
? static_cast<void> (0) : __assert_fail ("UnemittedDepMII->second.Dependants[&JD].count(Name) && \"Name is not listed as a dependant of unemitted dependency\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1344, __PRETTY_FUNCTION__))
;
1345 UnemittedDepMII->second.Dependants[&JD].erase(Name);
1346 if (UnemittedDepMII->second.Dependants[&JD].empty())
1347 UnemittedDepMII->second.Dependants.erase(&JD);
1348 }
1349 }
1350 MI.UnemittedDependencies.clear();
1351
1352 // Collect queries to be failed for this MII.
1353 AsynchronousSymbolQueryList ToDetach;
1354 for (auto &Q : MII->second.pendingQueries()) {
1355 // Add the query to the list to be failed and detach it.
1356 FailedQueries.insert(Q);
1357 ToDetach.push_back(Q);
1358 }
1359 for (auto &Q : ToDetach)
1360 Q->detach();
1361
1362 assert(MI.Dependants.empty() &&((MI.Dependants.empty() && "Can not delete MaterializingInfo with dependants still attached"
) ? static_cast<void> (0) : __assert_fail ("MI.Dependants.empty() && \"Can not delete MaterializingInfo with dependants still attached\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1363, __PRETTY_FUNCTION__))
1363 "Can not delete MaterializingInfo with dependants still attached")((MI.Dependants.empty() && "Can not delete MaterializingInfo with dependants still attached"
) ? static_cast<void> (0) : __assert_fail ("MI.Dependants.empty() && \"Can not delete MaterializingInfo with dependants still attached\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1363, __PRETTY_FUNCTION__))
;
1364 assert(MI.UnemittedDependencies.empty() &&((MI.UnemittedDependencies.empty() && "Can not delete MaterializingInfo with unemitted dependencies "
"still attached") ? static_cast<void> (0) : __assert_fail
("MI.UnemittedDependencies.empty() && \"Can not delete MaterializingInfo with unemitted dependencies \" \"still attached\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1366, __PRETTY_FUNCTION__))
1365 "Can not delete MaterializingInfo with unemitted dependencies "((MI.UnemittedDependencies.empty() && "Can not delete MaterializingInfo with unemitted dependencies "
"still attached") ? static_cast<void> (0) : __assert_fail
("MI.UnemittedDependencies.empty() && \"Can not delete MaterializingInfo with unemitted dependencies \" \"still attached\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1366, __PRETTY_FUNCTION__))
1366 "still attached")((MI.UnemittedDependencies.empty() && "Can not delete MaterializingInfo with unemitted dependencies "
"still attached") ? static_cast<void> (0) : __assert_fail
("MI.UnemittedDependencies.empty() && \"Can not delete MaterializingInfo with unemitted dependencies \" \"still attached\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1366, __PRETTY_FUNCTION__))
;
1367 assert(!MI.hasQueriesPending() &&((!MI.hasQueriesPending() && "Can not delete MaterializingInfo with queries pending"
) ? static_cast<void> (0) : __assert_fail ("!MI.hasQueriesPending() && \"Can not delete MaterializingInfo with queries pending\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1368, __PRETTY_FUNCTION__))
1368 "Can not delete MaterializingInfo with queries pending")((!MI.hasQueriesPending() && "Can not delete MaterializingInfo with queries pending"
) ? static_cast<void> (0) : __assert_fail ("!MI.hasQueriesPending() && \"Can not delete MaterializingInfo with queries pending\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1368, __PRETTY_FUNCTION__))
;
1369 JD.MaterializingInfos.erase(MII);
1370 }
1371 });
1372
1373 for (auto &Q : FailedQueries)
1374 Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbolsMap));
1375}
1376
1377void JITDylib::setSearchOrder(JITDylibSearchOrder NewSearchOrder,
1378 bool SearchThisJITDylibFirst) {
1379 ES.runSessionLocked([&]() {
1380 if (SearchThisJITDylibFirst) {
1381 SearchOrder.clear();
1382 if (NewSearchOrder.empty() || NewSearchOrder.front().first != this)
1383 SearchOrder.push_back(
1384 std::make_pair(this, JITDylibLookupFlags::MatchAllSymbols));
1385 SearchOrder.insert(SearchOrder.end(), NewSearchOrder.begin(),
1386 NewSearchOrder.end());
1387 } else
1388 SearchOrder = std::move(NewSearchOrder);
1389 });
1390}
1391
1392void JITDylib::addToSearchOrder(JITDylib &JD,
1393 JITDylibLookupFlags JDLookupFlags) {
1394 ES.runSessionLocked([&]() { SearchOrder.push_back({&JD, JDLookupFlags}); });
1395}
1396
1397void JITDylib::replaceInSearchOrder(JITDylib &OldJD, JITDylib &NewJD,
1398 JITDylibLookupFlags JDLookupFlags) {
1399 ES.runSessionLocked([&]() {
1400 for (auto &KV : SearchOrder)
1401 if (KV.first == &OldJD) {
1402 KV = {&NewJD, JDLookupFlags};
1403 break;
1404 }
1405 });
1406}
1407
1408void JITDylib::removeFromSearchOrder(JITDylib &JD) {
1409 ES.runSessionLocked([&]() {
1410 auto I = std::find_if(SearchOrder.begin(), SearchOrder.end(),
1411 [&](const JITDylibSearchOrder::value_type &KV) {
1412 return KV.first == &JD;
1413 });
1414 if (I != SearchOrder.end())
1415 SearchOrder.erase(I);
1416 });
1417}
1418
1419Error JITDylib::remove(const SymbolNameSet &Names) {
1420 return ES.runSessionLocked([&]() -> Error {
1421 using SymbolMaterializerItrPair =
1422 std::pair<SymbolTable::iterator, UnmaterializedInfosMap::iterator>;
1423 std::vector<SymbolMaterializerItrPair> SymbolsToRemove;
1424 SymbolNameSet Missing;
1425 SymbolNameSet Materializing;
1426
1427 for (auto &Name : Names) {
1428 auto I = Symbols.find(Name);
1429
1430 // Note symbol missing.
1431 if (I == Symbols.end()) {
1432 Missing.insert(Name);
1433 continue;
1434 }
1435
1436 // Note symbol materializing.
1437 if (I->second.getState() != SymbolState::NeverSearched &&
1438 I->second.getState() != SymbolState::Ready) {
1439 Materializing.insert(Name);
1440 continue;
1441 }
1442
1443 auto UMII = I->second.hasMaterializerAttached()
1444 ? UnmaterializedInfos.find(Name)
1445 : UnmaterializedInfos.end();
1446 SymbolsToRemove.push_back(std::make_pair(I, UMII));
1447 }
1448
1449 // If any of the symbols are not defined, return an error.
1450 if (!Missing.empty())
1451 return make_error<SymbolsNotFound>(std::move(Missing));
1452
1453 // If any of the symbols are currently materializing, return an error.
1454 if (!Materializing.empty())
1455 return make_error<SymbolsCouldNotBeRemoved>(std::move(Materializing));
1456
1457 // Remove the symbols.
1458 for (auto &SymbolMaterializerItrPair : SymbolsToRemove) {
1459 auto UMII = SymbolMaterializerItrPair.second;
1460
1461 // If there is a materializer attached, call discard.
1462 if (UMII != UnmaterializedInfos.end()) {
1463 UMII->second->MU->doDiscard(*this, UMII->first);
1464 UnmaterializedInfos.erase(UMII);
1465 }
1466
1467 auto SymI = SymbolMaterializerItrPair.first;
1468 Symbols.erase(SymI);
1469 }
1470
1471 return Error::success();
1472 });
1473}
1474
1475Expected<SymbolFlagsMap>
1476JITDylib::lookupFlags(LookupKind K, JITDylibLookupFlags JDLookupFlags,
1477 SymbolLookupSet LookupSet) {
1478 return ES.runSessionLocked([&, this]() -> Expected<SymbolFlagsMap> {
1479 SymbolFlagsMap Result;
1480 lookupFlagsImpl(Result, K, JDLookupFlags, LookupSet);
1481
1482 // Run any definition generators.
1483 for (auto &DG : DefGenerators) {
1484
1485 // Bail out early if we found everything.
1486 if (LookupSet.empty())
1487 break;
1488
1489 // Run this generator.
1490 if (auto Err = DG->tryToGenerate(K, *this, JDLookupFlags, LookupSet))
1491 return std::move(Err);
1492
1493 // Re-try the search.
1494 lookupFlagsImpl(Result, K, JDLookupFlags, LookupSet);
1495 }
1496
1497 return Result;
1498 });
1499}
1500
1501void JITDylib::lookupFlagsImpl(SymbolFlagsMap &Result, LookupKind K,
1502 JITDylibLookupFlags JDLookupFlags,
1503 SymbolLookupSet &LookupSet) {
1504
1505 LookupSet.forEachWithRemoval(
1506 [&](const SymbolStringPtr &Name, SymbolLookupFlags Flags) -> bool {
1507 auto I = Symbols.find(Name);
1508 if (I == Symbols.end())
1509 return false;
1510 assert(!Result.count(Name) && "Symbol already present in Flags map")((!Result.count(Name) && "Symbol already present in Flags map"
) ? static_cast<void> (0) : __assert_fail ("!Result.count(Name) && \"Symbol already present in Flags map\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1510, __PRETTY_FUNCTION__))
;
1511 Result[Name] = I->second.getFlags();
1512 return true;
1513 });
1514}
1515
1516Error JITDylib::lodgeQuery(MaterializationUnitList &MUs,
1517 std::shared_ptr<AsynchronousSymbolQuery> &Q,
1518 LookupKind K, JITDylibLookupFlags JDLookupFlags,
1519 SymbolLookupSet &Unresolved) {
1520 assert(Q && "Query can not be null")((Q && "Query can not be null") ? static_cast<void
> (0) : __assert_fail ("Q && \"Query can not be null\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1520, __PRETTY_FUNCTION__))
;
1521
1522 if (auto Err = lodgeQueryImpl(MUs, Q, K, JDLookupFlags, Unresolved))
1523 return Err;
1524
1525 // Run any definition generators.
1526 for (auto &DG : DefGenerators) {
1527
1528 // Bail out early if we have resolved everything.
1529 if (Unresolved.empty())
1530 break;
1531
1532 // Run the generator.
1533 if (auto Err = DG->tryToGenerate(K, *this, JDLookupFlags, Unresolved))
1534 return Err;
1535
1536 // Lodge query. This can not fail as any new definitions were added
1537 // by the generator under the session locked. Since they can't have
1538 // started materializing yet they can not have failed.
1539 cantFail(lodgeQueryImpl(MUs, Q, K, JDLookupFlags, Unresolved));
1540 }
1541
1542 return Error::success();
1543}
1544
1545Error JITDylib::lodgeQueryImpl(MaterializationUnitList &MUs,
1546 std::shared_ptr<AsynchronousSymbolQuery> &Q,
1547 LookupKind K, JITDylibLookupFlags JDLookupFlags,
1548 SymbolLookupSet &Unresolved) {
1549
1550 return Unresolved.forEachWithRemoval(
1551 [&](const SymbolStringPtr &Name,
1552 SymbolLookupFlags SymLookupFlags) -> Expected<bool> {
1553 // Search for name in symbols. If not found then continue without
1554 // removal.
1555 auto SymI = Symbols.find(Name);
1556 if (SymI == Symbols.end())
1557 return false;
1558
1559 // If this is a non exported symbol and we're matching exported symbols
1560 // only then skip this symbol without removal.
1561 if (!SymI->second.getFlags().isExported() &&
1562 JDLookupFlags == JITDylibLookupFlags::MatchExportedSymbolsOnly)
1563 return false;
1564
1565 // If we matched against this symbol but it is in the error state then
1566 // bail out and treat it as a failure to materialize.
1567 if (SymI->second.getFlags().hasError()) {
1568 auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
1569 (*FailedSymbolsMap)[this] = {Name};
1570 return make_error<FailedToMaterialize>(std::move(FailedSymbolsMap));
1571 }
1572
1573 // If this symbol already meets the required state for then notify the
1574 // query, then remove the symbol and continue.
1575 if (SymI->second.getState() >= Q->getRequiredState()) {
1576 Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
1577 return true;
1578 }
1579
1580 // Otherwise this symbol does not yet meet the required state. Check
1581 // whether it has a materializer attached, and if so prepare to run it.
1582 if (SymI->second.hasMaterializerAttached()) {
1583 assert(SymI->second.getAddress() == 0 &&((SymI->second.getAddress() == 0 && "Symbol not resolved but already has address?"
) ? static_cast<void> (0) : __assert_fail ("SymI->second.getAddress() == 0 && \"Symbol not resolved but already has address?\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1584, __PRETTY_FUNCTION__))
1584 "Symbol not resolved but already has address?")((SymI->second.getAddress() == 0 && "Symbol not resolved but already has address?"
) ? static_cast<void> (0) : __assert_fail ("SymI->second.getAddress() == 0 && \"Symbol not resolved but already has address?\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1584, __PRETTY_FUNCTION__))
;
1585 auto UMII = UnmaterializedInfos.find(Name);
1586 assert(UMII != UnmaterializedInfos.end() &&((UMII != UnmaterializedInfos.end() && "Lazy symbol should have UnmaterializedInfo"
) ? static_cast<void> (0) : __assert_fail ("UMII != UnmaterializedInfos.end() && \"Lazy symbol should have UnmaterializedInfo\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1587, __PRETTY_FUNCTION__))
1587 "Lazy symbol should have UnmaterializedInfo")((UMII != UnmaterializedInfos.end() && "Lazy symbol should have UnmaterializedInfo"
) ? static_cast<void> (0) : __assert_fail ("UMII != UnmaterializedInfos.end() && \"Lazy symbol should have UnmaterializedInfo\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1587, __PRETTY_FUNCTION__))
;
1588 auto MU = std::move(UMII->second->MU);
1589 assert(MU != nullptr && "Materializer should not be null")((MU != nullptr && "Materializer should not be null")
? static_cast<void> (0) : __assert_fail ("MU != nullptr && \"Materializer should not be null\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1589, __PRETTY_FUNCTION__))
;
1590
1591 // Move all symbols associated with this MaterializationUnit into
1592 // materializing state.
1593 for (auto &KV : MU->getSymbols()) {
1594 auto SymK = Symbols.find(KV.first);
1595 SymK->second.setMaterializerAttached(false);
1596 SymK->second.setState(SymbolState::Materializing);
1597 UnmaterializedInfos.erase(KV.first);
1598 }
1599
1600 // Add MU to the list of MaterializationUnits to be materialized.
1601 MUs.push_back(std::move(MU));
1602 }
1603
1604 // Add the query to the PendingQueries list and continue, deleting the
1605 // element.
1606 assert(SymI->second.getState() != SymbolState::NeverSearched &&((SymI->second.getState() != SymbolState::NeverSearched &&
SymI->second.getState() != SymbolState::Ready && "By this line the symbol should be materializing"
) ? static_cast<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-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1608, __PRETTY_FUNCTION__))
1607 SymI->second.getState() != SymbolState::Ready &&((SymI->second.getState() != SymbolState::NeverSearched &&
SymI->second.getState() != SymbolState::Ready && "By this line the symbol should be materializing"
) ? static_cast<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-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1608, __PRETTY_FUNCTION__))
1608 "By this line the symbol should be materializing")((SymI->second.getState() != SymbolState::NeverSearched &&
SymI->second.getState() != SymbolState::Ready && "By this line the symbol should be materializing"
) ? static_cast<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-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1608, __PRETTY_FUNCTION__))
;
1609 auto &MI = MaterializingInfos[Name];
1610 MI.addQuery(Q);
1611 Q->addQueryDependence(*this, Name);
1612 return true;
1613 });
1614}
1615
1616Expected<SymbolNameSet>
1617JITDylib::legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
1618 SymbolNameSet Names) {
1619 assert(Q && "Query can not be null")((Q && "Query can not be null") ? static_cast<void
> (0) : __assert_fail ("Q && \"Query can not be null\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1619, __PRETTY_FUNCTION__))
;
1
'?' condition is true
1620
1621 ES.runOutstandingMUs();
1622
1623 bool QueryComplete = false;
1624 std::vector<std::unique_ptr<MaterializationUnit>> MUs;
1625
1626 SymbolLookupSet Unresolved(Names);
1627 auto Err = ES.runSessionLocked([&, this]() -> Error {
1628 QueryComplete = lookupImpl(Q, MUs, Unresolved);
1629
1630 // Run any definition generators.
1631 for (auto &DG : DefGenerators) {
1632
1633 // Bail out early if we have resolved everything.
1634 if (Unresolved.empty())
1635 break;
1636
1637 assert(!QueryComplete && "query complete but unresolved symbols remain?")((!QueryComplete && "query complete but unresolved symbols remain?"
) ? static_cast<void> (0) : __assert_fail ("!QueryComplete && \"query complete but unresolved symbols remain?\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1637, __PRETTY_FUNCTION__))
;
1638 if (auto Err = DG->tryToGenerate(LookupKind::Static, *this,
1639 JITDylibLookupFlags::MatchAllSymbols,
1640 Unresolved))
1641 return Err;
1642
1643 if (!Unresolved.empty())
1644 QueryComplete = lookupImpl(Q, MUs, Unresolved);
1645 }
1646 return Error::success();
1647 });
1648
1649 if (Err)
2
Taking false branch
1650 return std::move(Err);
1651
1652 assert((MUs.empty() || !QueryComplete) &&(((MUs.empty() || !QueryComplete) && "If action flags are set, there should be no work to do (so no MUs)"
) ? static_cast<void> (0) : __assert_fail ("(MUs.empty() || !QueryComplete) && \"If action flags are set, there should be no work to do (so no MUs)\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1653, __PRETTY_FUNCTION__))
3
Assuming the condition is true
4
'?' condition is true
1653 "If action flags are set, there should be no work to do (so no MUs)")(((MUs.empty() || !QueryComplete) && "If action flags are set, there should be no work to do (so no MUs)"
) ? static_cast<void> (0) : __assert_fail ("(MUs.empty() || !QueryComplete) && \"If action flags are set, there should be no work to do (so no MUs)\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1653, __PRETTY_FUNCTION__))
;
1654
1655 if (QueryComplete)
5
Assuming 'QueryComplete' is true
6
Taking true branch
1656 Q->handleComplete();
7
Calling 'AsynchronousSymbolQuery::handleComplete'
1657
1658 // FIXME: Swap back to the old code below once RuntimeDyld works with
1659 // callbacks from asynchronous queries.
1660 // Add MUs to the OutstandingMUs list.
1661 {
1662 std::lock_guard<std::recursive_mutex> Lock(ES.OutstandingMUsMutex);
1663 for (auto &MU : MUs)
1664 ES.OutstandingMUs.push_back(make_pair(this, std::move(MU)));
1665 }
1666 ES.runOutstandingMUs();
1667
1668 // Dispatch any required MaterializationUnits for materialization.
1669 // for (auto &MU : MUs)
1670 // ES.dispatchMaterialization(*this, std::move(MU));
1671
1672 SymbolNameSet RemainingSymbols;
1673 for (auto &KV : Unresolved)
1674 RemainingSymbols.insert(KV.first);
1675
1676 return RemainingSymbols;
1677}
1678
1679bool JITDylib::lookupImpl(
1680 std::shared_ptr<AsynchronousSymbolQuery> &Q,
1681 std::vector<std::unique_ptr<MaterializationUnit>> &MUs,
1682 SymbolLookupSet &Unresolved) {
1683 bool QueryComplete = false;
1684
1685 std::vector<SymbolStringPtr> ToRemove;
1686 Unresolved.forEachWithRemoval(
1687 [&](const SymbolStringPtr &Name, SymbolLookupFlags Flags) -> bool {
1688 // Search for the name in Symbols. Skip without removing if not found.
1689 auto SymI = Symbols.find(Name);
1690 if (SymI == Symbols.end())
1691 return false;
1692
1693 // If the symbol is already in the required state then notify the query
1694 // and remove.
1695 if (SymI->second.getState() >= Q->getRequiredState()) {
1696 Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
1697 if (Q->isComplete())
1698 QueryComplete = true;
1699 return true;
1700 }
1701
1702 // If the symbol is lazy, get the MaterialiaztionUnit for it.
1703 if (SymI->second.hasMaterializerAttached()) {
1704 assert(SymI->second.getAddress() == 0 &&((SymI->second.getAddress() == 0 && "Lazy symbol should not have a resolved address"
) ? static_cast<void> (0) : __assert_fail ("SymI->second.getAddress() == 0 && \"Lazy symbol should not have a resolved address\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1705, __PRETTY_FUNCTION__))
1705 "Lazy symbol should not have a resolved address")((SymI->second.getAddress() == 0 && "Lazy symbol should not have a resolved address"
) ? static_cast<void> (0) : __assert_fail ("SymI->second.getAddress() == 0 && \"Lazy symbol should not have a resolved address\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1705, __PRETTY_FUNCTION__))
;
1706 auto UMII = UnmaterializedInfos.find(Name);
1707 assert(UMII != UnmaterializedInfos.end() &&((UMII != UnmaterializedInfos.end() && "Lazy symbol should have UnmaterializedInfo"
) ? static_cast<void> (0) : __assert_fail ("UMII != UnmaterializedInfos.end() && \"Lazy symbol should have UnmaterializedInfo\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1708, __PRETTY_FUNCTION__))
1708 "Lazy symbol should have UnmaterializedInfo")((UMII != UnmaterializedInfos.end() && "Lazy symbol should have UnmaterializedInfo"
) ? static_cast<void> (0) : __assert_fail ("UMII != UnmaterializedInfos.end() && \"Lazy symbol should have UnmaterializedInfo\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1708, __PRETTY_FUNCTION__))
;
1709 auto MU = std::move(UMII->second->MU);
1710 assert(MU != nullptr && "Materializer should not be null")((MU != nullptr && "Materializer should not be null")
? static_cast<void> (0) : __assert_fail ("MU != nullptr && \"Materializer should not be null\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1710, __PRETTY_FUNCTION__))
;
1711
1712 // Kick all symbols associated with this MaterializationUnit into
1713 // materializing state.
1714 for (auto &KV : MU->getSymbols()) {
1715 auto SymK = Symbols.find(KV.first);
1716 assert(SymK != Symbols.end() && "Missing symbol table entry")((SymK != Symbols.end() && "Missing symbol table entry"
) ? static_cast<void> (0) : __assert_fail ("SymK != Symbols.end() && \"Missing symbol table entry\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1716, __PRETTY_FUNCTION__))
;
1717 SymK->second.setState(SymbolState::Materializing);
1718 SymK->second.setMaterializerAttached(false);
1719 UnmaterializedInfos.erase(KV.first);
1720 }
1721
1722 // Add MU to the list of MaterializationUnits to be materialized.
1723 MUs.push_back(std::move(MU));
1724 }
1725
1726 // Add the query to the PendingQueries list.
1727 assert(SymI->second.getState() != SymbolState::NeverSearched &&((SymI->second.getState() != SymbolState::NeverSearched &&
SymI->second.getState() != SymbolState::Ready && "By this line the symbol should be materializing"
) ? static_cast<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-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1729, __PRETTY_FUNCTION__))
1728 SymI->second.getState() != SymbolState::Ready &&((SymI->second.getState() != SymbolState::NeverSearched &&
SymI->second.getState() != SymbolState::Ready && "By this line the symbol should be materializing"
) ? static_cast<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-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1729, __PRETTY_FUNCTION__))
1729 "By this line the symbol should be materializing")((SymI->second.getState() != SymbolState::NeverSearched &&
SymI->second.getState() != SymbolState::Ready && "By this line the symbol should be materializing"
) ? static_cast<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-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1729, __PRETTY_FUNCTION__))
;
1730 auto &MI = MaterializingInfos[Name];
1731 MI.addQuery(Q);
1732 Q->addQueryDependence(*this, Name);
1733 return true;
1734 });
1735
1736 return QueryComplete;
1737}
1738
1739void JITDylib::dump(raw_ostream &OS) {
1740 ES.runSessionLocked([&, this]() {
1741 OS << "JITDylib \"" << JITDylibName << "\" (ES: "
1742 << format("0x%016" PRIx64"l" "x", reinterpret_cast<uintptr_t>(&ES)) << "):\n"
1743 << "Search order: " << SearchOrder << "\n"
1744 << "Symbol table:\n";
1745
1746 for (auto &KV : Symbols) {
1747 OS << " \"" << *KV.first << "\": ";
1748 if (auto Addr = KV.second.getAddress())
1749 OS << format("0x%016" PRIx64"l" "x", Addr) << ", " << KV.second.getFlags()
1750 << " ";
1751 else
1752 OS << "<not resolved> ";
1753
1754 OS << KV.second.getState();
1755
1756 if (KV.second.hasMaterializerAttached()) {
1757 OS << " (Materializer ";
1758 auto I = UnmaterializedInfos.find(KV.first);
1759 assert(I != UnmaterializedInfos.end() &&((I != UnmaterializedInfos.end() && "Lazy symbol should have UnmaterializedInfo"
) ? static_cast<void> (0) : __assert_fail ("I != UnmaterializedInfos.end() && \"Lazy symbol should have UnmaterializedInfo\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1760, __PRETTY_FUNCTION__))
1760 "Lazy symbol should have UnmaterializedInfo")((I != UnmaterializedInfos.end() && "Lazy symbol should have UnmaterializedInfo"
) ? static_cast<void> (0) : __assert_fail ("I != UnmaterializedInfos.end() && \"Lazy symbol should have UnmaterializedInfo\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1760, __PRETTY_FUNCTION__))
;
1761 OS << I->second->MU.get() << ")\n";
1762 } else
1763 OS << "\n";
1764 }
1765
1766 if (!MaterializingInfos.empty())
1767 OS << " MaterializingInfos entries:\n";
1768 for (auto &KV : MaterializingInfos) {
1769 OS << " \"" << *KV.first << "\":\n"
1770 << " " << KV.second.pendingQueries().size()
1771 << " pending queries: { ";
1772 for (const auto &Q : KV.second.pendingQueries())
1773 OS << Q.get() << " (" << Q->getRequiredState() << ") ";
1774 OS << "}\n Dependants:\n";
1775 for (auto &KV2 : KV.second.Dependants)
1776 OS << " " << KV2.first->getName() << ": " << KV2.second << "\n";
1777 OS << " Unemitted Dependencies:\n";
1778 for (auto &KV2 : KV.second.UnemittedDependencies)
1779 OS << " " << KV2.first->getName() << ": " << KV2.second << "\n";
1780 }
1781 });
1782}
1783
1784void JITDylib::MaterializingInfo::addQuery(
1785 std::shared_ptr<AsynchronousSymbolQuery> Q) {
1786
1787 auto I = std::lower_bound(
1788 PendingQueries.rbegin(), PendingQueries.rend(), Q->getRequiredState(),
1789 [](const std::shared_ptr<AsynchronousSymbolQuery> &V, SymbolState S) {
1790 return V->getRequiredState() <= S;
1791 });
1792 PendingQueries.insert(I.base(), std::move(Q));
1793}
1794
1795void JITDylib::MaterializingInfo::removeQuery(
1796 const AsynchronousSymbolQuery &Q) {
1797 // FIXME: Implement 'find_as' for shared_ptr<T>/T*.
1798 auto I =
1799 std::find_if(PendingQueries.begin(), PendingQueries.end(),
1800 [&Q](const std::shared_ptr<AsynchronousSymbolQuery> &V) {
1801 return V.get() == &Q;
1802 });
1803 assert(I != PendingQueries.end() &&((I != PendingQueries.end() && "Query is not attached to this MaterializingInfo"
) ? static_cast<void> (0) : __assert_fail ("I != PendingQueries.end() && \"Query is not attached to this MaterializingInfo\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1804, __PRETTY_FUNCTION__))
1804 "Query is not attached to this MaterializingInfo")((I != PendingQueries.end() && "Query is not attached to this MaterializingInfo"
) ? static_cast<void> (0) : __assert_fail ("I != PendingQueries.end() && \"Query is not attached to this MaterializingInfo\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1804, __PRETTY_FUNCTION__))
;
1805 PendingQueries.erase(I);
1806}
1807
1808JITDylib::AsynchronousSymbolQueryList
1809JITDylib::MaterializingInfo::takeQueriesMeeting(SymbolState RequiredState) {
1810 AsynchronousSymbolQueryList Result;
1811 while (!PendingQueries.empty()) {
1812 if (PendingQueries.back()->getRequiredState() > RequiredState)
1813 break;
1814
1815 Result.push_back(std::move(PendingQueries.back()));
1816 PendingQueries.pop_back();
1817 }
1818
1819 return Result;
1820}
1821
1822JITDylib::JITDylib(ExecutionSession &ES, std::string Name)
1823 : ES(ES), JITDylibName(std::move(Name)) {
1824 SearchOrder.push_back({this, JITDylibLookupFlags::MatchAllSymbols});
1825}
1826
1827Error JITDylib::defineImpl(MaterializationUnit &MU) {
1828 SymbolNameSet Duplicates;
1829 std::vector<SymbolStringPtr> ExistingDefsOverridden;
1830 std::vector<SymbolStringPtr> MUDefsOverridden;
1831
1832 for (const auto &KV : MU.getSymbols()) {
1833 auto I = Symbols.find(KV.first);
1834
1835 if (I != Symbols.end()) {
1836 if (KV.second.isStrong()) {
1837 if (I->second.getFlags().isStrong() ||
1838 I->second.getState() > SymbolState::NeverSearched)
1839 Duplicates.insert(KV.first);
1840 else {
1841 assert(I->second.getState() == SymbolState::NeverSearched &&((I->second.getState() == SymbolState::NeverSearched &&
"Overridden existing def should be in the never-searched " "state"
) ? static_cast<void> (0) : __assert_fail ("I->second.getState() == SymbolState::NeverSearched && \"Overridden existing def should be in the never-searched \" \"state\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1843, __PRETTY_FUNCTION__))
1842 "Overridden existing def should be in the never-searched "((I->second.getState() == SymbolState::NeverSearched &&
"Overridden existing def should be in the never-searched " "state"
) ? static_cast<void> (0) : __assert_fail ("I->second.getState() == SymbolState::NeverSearched && \"Overridden existing def should be in the never-searched \" \"state\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1843, __PRETTY_FUNCTION__))
1843 "state")((I->second.getState() == SymbolState::NeverSearched &&
"Overridden existing def should be in the never-searched " "state"
) ? static_cast<void> (0) : __assert_fail ("I->second.getState() == SymbolState::NeverSearched && \"Overridden existing def should be in the never-searched \" \"state\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1843, __PRETTY_FUNCTION__))
;
1844 ExistingDefsOverridden.push_back(KV.first);
1845 }
1846 } else
1847 MUDefsOverridden.push_back(KV.first);
1848 }
1849 }
1850
1851 // If there were any duplicate definitions then bail out.
1852 if (!Duplicates.empty())
1853 return make_error<DuplicateDefinition>(std::string(**Duplicates.begin()));
1854
1855 // Discard any overridden defs in this MU.
1856 for (auto &S : MUDefsOverridden)
1857 MU.doDiscard(*this, S);
1858
1859 // Discard existing overridden defs.
1860 for (auto &S : ExistingDefsOverridden) {
1861
1862 auto UMII = UnmaterializedInfos.find(S);
1863 assert(UMII != UnmaterializedInfos.end() &&((UMII != UnmaterializedInfos.end() && "Overridden existing def should have an UnmaterializedInfo"
) ? static_cast<void> (0) : __assert_fail ("UMII != UnmaterializedInfos.end() && \"Overridden existing def should have an UnmaterializedInfo\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1864, __PRETTY_FUNCTION__))
1864 "Overridden existing def should have an UnmaterializedInfo")((UMII != UnmaterializedInfos.end() && "Overridden existing def should have an UnmaterializedInfo"
) ? static_cast<void> (0) : __assert_fail ("UMII != UnmaterializedInfos.end() && \"Overridden existing def should have an UnmaterializedInfo\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1864, __PRETTY_FUNCTION__))
;
1865 UMII->second->MU->doDiscard(*this, S);
1866 }
1867
1868 // Finally, add the defs from this MU.
1869 for (auto &KV : MU.getSymbols()) {
1870 auto &SymEntry = Symbols[KV.first];
1871 SymEntry.setFlags(KV.second);
1872 SymEntry.setState(SymbolState::NeverSearched);
1873 SymEntry.setMaterializerAttached(true);
1874 }
1875
1876 return Error::success();
1877}
1878
1879void JITDylib::detachQueryHelper(AsynchronousSymbolQuery &Q,
1880 const SymbolNameSet &QuerySymbols) {
1881 for (auto &QuerySymbol : QuerySymbols) {
1882 assert(MaterializingInfos.count(QuerySymbol) &&((MaterializingInfos.count(QuerySymbol) && "QuerySymbol does not have MaterializingInfo"
) ? static_cast<void> (0) : __assert_fail ("MaterializingInfos.count(QuerySymbol) && \"QuerySymbol does not have MaterializingInfo\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1883, __PRETTY_FUNCTION__))
1883 "QuerySymbol does not have MaterializingInfo")((MaterializingInfos.count(QuerySymbol) && "QuerySymbol does not have MaterializingInfo"
) ? static_cast<void> (0) : __assert_fail ("MaterializingInfos.count(QuerySymbol) && \"QuerySymbol does not have MaterializingInfo\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1883, __PRETTY_FUNCTION__))
;
1884 auto &MI = MaterializingInfos[QuerySymbol];
1885 MI.removeQuery(Q);
1886 }
1887}
1888
1889void JITDylib::transferEmittedNodeDependencies(
1890 MaterializingInfo &DependantMI, const SymbolStringPtr &DependantName,
1891 MaterializingInfo &EmittedMI) {
1892 for (auto &KV : EmittedMI.UnemittedDependencies) {
1893 auto &DependencyJD = *KV.first;
1894 SymbolNameSet *UnemittedDependenciesOnDependencyJD = nullptr;
1895
1896 for (auto &DependencyName : KV.second) {
1897 auto &DependencyMI = DependencyJD.MaterializingInfos[DependencyName];
1898
1899 // Do not add self dependencies.
1900 if (&DependencyMI == &DependantMI)
1901 continue;
1902
1903 // If we haven't looked up the dependencies for DependencyJD yet, do it
1904 // now and cache the result.
1905 if (!UnemittedDependenciesOnDependencyJD)
1906 UnemittedDependenciesOnDependencyJD =
1907 &DependantMI.UnemittedDependencies[&DependencyJD];
1908
1909 DependencyMI.Dependants[this].insert(DependantName);
1910 UnemittedDependenciesOnDependencyJD->insert(DependencyName);
1911 }
1912 }
1913}
1914
1915Platform::~Platform() {}
1916
1917Expected<DenseMap<JITDylib *, SymbolMap>> Platform::lookupInitSymbols(
1918 ExecutionSession &ES,
1919 const DenseMap<JITDylib *, SymbolLookupSet> &InitSyms) {
1920
1921 DenseMap<JITDylib *, SymbolMap> CompoundResult;
1922 Error CompoundErr = Error::success();
1923 std::mutex LookupMutex;
1924 std::condition_variable CV;
1925 uint64_t Count = InitSyms.size();
1926
1927 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)
1928 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)
1929 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)
1930 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)
1931 })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)
;
1932
1933 for (auto &KV : InitSyms) {
1934 auto *JD = KV.first;
1935 auto Names = std::move(KV.second);
1936 ES.lookup(
1937 LookupKind::Static,
1938 JITDylibSearchOrder({{JD, JITDylibLookupFlags::MatchAllSymbols}}),
1939 std::move(Names), SymbolState::Ready,
1940 [&, JD](Expected<SymbolMap> Result) {
1941 {
1942 std::lock_guard<std::mutex> Lock(LookupMutex);
1943 --Count;
1944 if (Result) {
1945 assert(!CompoundResult.count(JD) &&((!CompoundResult.count(JD) && "Duplicate JITDylib in lookup?"
) ? static_cast<void> (0) : __assert_fail ("!CompoundResult.count(JD) && \"Duplicate JITDylib in lookup?\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1946, __PRETTY_FUNCTION__))
1946 "Duplicate JITDylib in lookup?")((!CompoundResult.count(JD) && "Duplicate JITDylib in lookup?"
) ? static_cast<void> (0) : __assert_fail ("!CompoundResult.count(JD) && \"Duplicate JITDylib in lookup?\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1946, __PRETTY_FUNCTION__))
;
1947 CompoundResult[JD] = std::move(*Result);
1948 } else
1949 CompoundErr =
1950 joinErrors(std::move(CompoundErr), Result.takeError());
1951 }
1952 CV.notify_one();
1953 },
1954 NoDependenciesToRegister);
1955 }
1956
1957 std::unique_lock<std::mutex> Lock(LookupMutex);
1958 CV.wait(Lock, [&] { return Count == 0 || CompoundErr; });
1959
1960 if (CompoundErr)
1961 return std::move(CompoundErr);
1962
1963 return std::move(CompoundResult);
1964}
1965
1966ExecutionSession::ExecutionSession(std::shared_ptr<SymbolStringPool> SSP)
1967 : SSP(SSP ? std::move(SSP) : std::make_shared<SymbolStringPool>()) {
1968}
1969
1970JITDylib *ExecutionSession::getJITDylibByName(StringRef Name) {
1971 return runSessionLocked([&, this]() -> JITDylib * {
1972 for (auto &JD : JDs)
1973 if (JD->getName() == Name)
1974 return JD.get();
1975 return nullptr;
1976 });
1977}
1978
1979JITDylib &ExecutionSession::createBareJITDylib(std::string Name) {
1980 assert(!getJITDylibByName(Name) && "JITDylib with that name already exists")((!getJITDylibByName(Name) && "JITDylib with that name already exists"
) ? static_cast<void> (0) : __assert_fail ("!getJITDylibByName(Name) && \"JITDylib with that name already exists\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1980, __PRETTY_FUNCTION__))
;
1981 return runSessionLocked([&, this]() -> JITDylib & {
1982 JDs.push_back(
1983 std::unique_ptr<JITDylib>(new JITDylib(*this, std::move(Name))));
1984 return *JDs.back();
1985 });
1986}
1987
1988Expected<JITDylib &> ExecutionSession::createJITDylib(std::string Name) {
1989 auto &JD = createBareJITDylib(Name);
1990 if (P)
1991 if (auto Err = P->setupJITDylib(JD))
1992 return std::move(Err);
1993 return JD;
1994}
1995
1996void ExecutionSession::legacyFailQuery(AsynchronousSymbolQuery &Q, Error Err) {
1997 assert(!!Err && "Error should be in failure state")((!!Err && "Error should be in failure state") ? static_cast
<void> (0) : __assert_fail ("!!Err && \"Error should be in failure state\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 1997, __PRETTY_FUNCTION__))
;
1998
1999 bool SendErrorToQuery;
2000 runSessionLocked([&]() {
2001 Q.detach();
2002 SendErrorToQuery = Q.canStillFail();
2003 });
2004
2005 if (SendErrorToQuery)
2006 Q.handleFailed(std::move(Err));
2007 else
2008 reportError(std::move(Err));
2009}
2010
2011Expected<SymbolMap> ExecutionSession::legacyLookup(
2012 LegacyAsyncLookupFunction AsyncLookup, SymbolNameSet Names,
2013 SymbolState RequiredState,
2014 RegisterDependenciesFunction RegisterDependencies) {
2015#if LLVM_ENABLE_THREADS1
2016 // In the threaded case we use promises to return the results.
2017 std::promise<SymbolMap> PromisedResult;
2018 Error ResolutionError = Error::success();
2019 auto NotifyComplete = [&](Expected<SymbolMap> R) {
2020 if (R)
2021 PromisedResult.set_value(std::move(*R));
2022 else {
2023 ErrorAsOutParameter _(&ResolutionError);
2024 ResolutionError = R.takeError();
2025 PromisedResult.set_value(SymbolMap());
2026 }
2027 };
2028#else
2029 SymbolMap Result;
2030 Error ResolutionError = Error::success();
2031
2032 auto NotifyComplete = [&](Expected<SymbolMap> R) {
2033 ErrorAsOutParameter _(&ResolutionError);
2034 if (R)
2035 Result = std::move(*R);
2036 else
2037 ResolutionError = R.takeError();
2038 };
2039#endif
2040
2041 auto Query = std::make_shared<AsynchronousSymbolQuery>(
2042 SymbolLookupSet(Names), RequiredState, std::move(NotifyComplete));
2043 // FIXME: This should be run session locked along with the registration code
2044 // and error reporting below.
2045 SymbolNameSet UnresolvedSymbols = AsyncLookup(Query, std::move(Names));
2046
2047 // If the query was lodged successfully then register the dependencies,
2048 // otherwise fail it with an error.
2049 if (UnresolvedSymbols.empty())
2050 RegisterDependencies(Query->QueryRegistrations);
2051 else {
2052 bool DeliverError = runSessionLocked([&]() {
2053 Query->detach();
2054 return Query->canStillFail();
2055 });
2056 auto Err = make_error<SymbolsNotFound>(std::move(UnresolvedSymbols));
2057 if (DeliverError)
2058 Query->handleFailed(std::move(Err));
2059 else
2060 reportError(std::move(Err));
2061 }
2062
2063#if LLVM_ENABLE_THREADS1
2064 auto ResultFuture = PromisedResult.get_future();
2065 auto Result = ResultFuture.get();
2066 if (ResolutionError)
2067 return std::move(ResolutionError);
2068 return std::move(Result);
2069
2070#else
2071 if (ResolutionError)
2072 return std::move(ResolutionError);
2073
2074 return Result;
2075#endif
2076}
2077
2078void ExecutionSession::lookup(
2079 LookupKind K, const JITDylibSearchOrder &SearchOrder,
2080 SymbolLookupSet Symbols, SymbolState RequiredState,
2081 SymbolsResolvedCallback NotifyComplete,
2082 RegisterDependenciesFunction RegisterDependencies) {
2083
2084 LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { runSessionLocked([&]() { dbgs() << "Looking up "
<< Symbols << " in " << SearchOrder <<
" (required state: " << RequiredState << ")\n"; }
); }; } } while (false)
2085 runSessionLocked([&]() {do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { runSessionLocked([&]() { dbgs() << "Looking up "
<< Symbols << " in " << SearchOrder <<
" (required state: " << RequiredState << ")\n"; }
); }; } } while (false)
2086 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)
2087 << " (required state: " << RequiredState << ")\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { runSessionLocked([&]() { dbgs() << "Looking up "
<< Symbols << " in " << SearchOrder <<
" (required state: " << RequiredState << ")\n"; }
); }; } } while (false)
2088 });do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { runSessionLocked([&]() { dbgs() << "Looking up "
<< Symbols << " in " << SearchOrder <<
" (required state: " << RequiredState << ")\n"; }
); }; } } while (false)
2089 })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("orc")) { { runSessionLocked([&]() { dbgs() << "Looking up "
<< Symbols << " in " << SearchOrder <<
" (required state: " << RequiredState << ")\n"; }
); }; } } while (false)
;
2090
2091 // lookup can be re-entered recursively if running on a single thread. Run any
2092 // outstanding MUs in case this query depends on them, otherwise this lookup
2093 // will starve waiting for a result from an MU that is stuck in the queue.
2094 runOutstandingMUs();
2095
2096 auto Unresolved = std::move(Symbols);
2097 std::map<JITDylib *, MaterializationUnitList> CollectedMUsMap;
2098 auto Q = std::make_shared<AsynchronousSymbolQuery>(Unresolved, RequiredState,
2099 std::move(NotifyComplete));
2100 bool QueryComplete = false;
2101
2102 auto LodgingErr = runSessionLocked([&]() -> Error {
2103 auto LodgeQuery = [&]() -> Error {
2104 for (auto &KV : SearchOrder) {
2105 assert(KV.first && "JITDylibList entries must not be null")((KV.first && "JITDylibList entries must not be null"
) ? static_cast<void> (0) : __assert_fail ("KV.first && \"JITDylibList entries must not be null\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 2105, __PRETTY_FUNCTION__))
;
2106 assert(!CollectedMUsMap.count(KV.first) &&((!CollectedMUsMap.count(KV.first) && "JITDylibList should not contain duplicate entries"
) ? static_cast<void> (0) : __assert_fail ("!CollectedMUsMap.count(KV.first) && \"JITDylibList should not contain duplicate entries\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 2107, __PRETTY_FUNCTION__))
2107 "JITDylibList should not contain duplicate entries")((!CollectedMUsMap.count(KV.first) && "JITDylibList should not contain duplicate entries"
) ? static_cast<void> (0) : __assert_fail ("!CollectedMUsMap.count(KV.first) && \"JITDylibList should not contain duplicate entries\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 2107, __PRETTY_FUNCTION__))
;
2108
2109 auto &JD = *KV.first;
2110 auto JDLookupFlags = KV.second;
2111 if (auto Err = JD.lodgeQuery(CollectedMUsMap[&JD], Q, K, JDLookupFlags,
2112 Unresolved))
2113 return Err;
2114 }
2115
2116 // Strip any weakly referenced symbols that were not found.
2117 Unresolved.forEachWithRemoval(
2118 [&](const SymbolStringPtr &Name, SymbolLookupFlags Flags) {
2119 if (Flags == SymbolLookupFlags::WeaklyReferencedSymbol) {
2120 Q->dropSymbol(Name);
2121 return true;
2122 }
2123 return false;
2124 });
2125
2126 if (!Unresolved.empty())
2127 return make_error<SymbolsNotFound>(Unresolved.getSymbolNames());
2128
2129 return Error::success();
2130 };
2131
2132 if (auto Err = LodgeQuery()) {
2133 // Query failed.
2134
2135 // Disconnect the query from its dependencies.
2136 Q->detach();
2137
2138 // Replace the MUs.
2139 for (auto &KV : CollectedMUsMap)
2140 for (auto &MU : KV.second)
2141 KV.first->replace(std::move(MU));
2142
2143 return Err;
2144 }
2145
2146 // Query lodged successfully.
2147
2148 // Record whether this query is fully ready / resolved. We will use
2149 // this to call handleFullyResolved/handleFullyReady outside the session
2150 // lock.
2151 QueryComplete = Q->isComplete();
2152
2153 // Call the register dependencies function.
2154 if (RegisterDependencies && !Q->QueryRegistrations.empty())
2155 RegisterDependencies(Q->QueryRegistrations);
2156
2157 return Error::success();
2158 });
2159
2160 if (LodgingErr) {
2161 Q->handleFailed(std::move(LodgingErr));
2162 return;
2163 }
2164
2165 if (QueryComplete)
2166 Q->handleComplete();
2167
2168 // Move the MUs to the OutstandingMUs list, then materialize.
2169 {
2170 std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
2171
2172 for (auto &KV : CollectedMUsMap)
2173 for (auto &MU : KV.second)
2174 OutstandingMUs.push_back(std::make_pair(KV.first, std::move(MU)));
2175 }
2176
2177 runOutstandingMUs();
2178}
2179
2180Expected<SymbolMap>
2181ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder,
2182 const SymbolLookupSet &Symbols, LookupKind K,
2183 SymbolState RequiredState,
2184 RegisterDependenciesFunction RegisterDependencies) {
2185#if LLVM_ENABLE_THREADS1
2186 // In the threaded case we use promises to return the results.
2187 std::promise<SymbolMap> PromisedResult;
2188 Error ResolutionError = Error::success();
2189
2190 auto NotifyComplete = [&](Expected<SymbolMap> R) {
2191 if (R)
2192 PromisedResult.set_value(std::move(*R));
2193 else {
2194 ErrorAsOutParameter _(&ResolutionError);
2195 ResolutionError = R.takeError();
2196 PromisedResult.set_value(SymbolMap());
2197 }
2198 };
2199
2200#else
2201 SymbolMap Result;
2202 Error ResolutionError = Error::success();
2203
2204 auto NotifyComplete = [&](Expected<SymbolMap> R) {
2205 ErrorAsOutParameter _(&ResolutionError);
2206 if (R)
2207 Result = std::move(*R);
2208 else
2209 ResolutionError = R.takeError();
2210 };
2211#endif
2212
2213 // Perform the asynchronous lookup.
2214 lookup(K, SearchOrder, Symbols, RequiredState, NotifyComplete,
2215 RegisterDependencies);
2216
2217#if LLVM_ENABLE_THREADS1
2218 auto ResultFuture = PromisedResult.get_future();
2219 auto Result = ResultFuture.get();
2220
2221 if (ResolutionError)
2222 return std::move(ResolutionError);
2223
2224 return std::move(Result);
2225
2226#else
2227 if (ResolutionError)
2228 return std::move(ResolutionError);
2229
2230 return Result;
2231#endif
2232}
2233
2234Expected<JITEvaluatedSymbol>
2235ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder,
2236 SymbolStringPtr Name, SymbolState RequiredState) {
2237 SymbolLookupSet Names({Name});
2238
2239 if (auto ResultMap = lookup(SearchOrder, std::move(Names), LookupKind::Static,
2240 RequiredState, NoDependenciesToRegister)) {
2241 assert(ResultMap->size() == 1 && "Unexpected number of results")((ResultMap->size() == 1 && "Unexpected number of results"
) ? static_cast<void> (0) : __assert_fail ("ResultMap->size() == 1 && \"Unexpected number of results\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 2241, __PRETTY_FUNCTION__))
;
2242 assert(ResultMap->count(Name) && "Missing result for symbol")((ResultMap->count(Name) && "Missing result for symbol"
) ? static_cast<void> (0) : __assert_fail ("ResultMap->count(Name) && \"Missing result for symbol\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 2242, __PRETTY_FUNCTION__))
;
2243 return std::move(ResultMap->begin()->second);
2244 } else
2245 return ResultMap.takeError();
2246}
2247
2248Expected<JITEvaluatedSymbol>
2249ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, SymbolStringPtr Name,
2250 SymbolState RequiredState) {
2251 return lookup(makeJITDylibSearchOrder(SearchOrder), Name, RequiredState);
2252}
2253
2254Expected<JITEvaluatedSymbol>
2255ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, StringRef Name,
2256 SymbolState RequiredState) {
2257 return lookup(SearchOrder, intern(Name), RequiredState);
2258}
2259
2260void ExecutionSession::dump(raw_ostream &OS) {
2261 runSessionLocked([this, &OS]() {
2262 for (auto &JD : JDs)
2263 JD->dump(OS);
2264 });
2265}
2266
2267void ExecutionSession::runOutstandingMUs() {
2268 while (1) {
2269 std::pair<JITDylib *, std::unique_ptr<MaterializationUnit>> JITDylibAndMU;
2270
2271 {
2272 std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
2273 if (!OutstandingMUs.empty()) {
2274 JITDylibAndMU = std::move(OutstandingMUs.back());
2275 OutstandingMUs.pop_back();
2276 }
2277 }
2278
2279 if (JITDylibAndMU.first) {
2280 assert(JITDylibAndMU.second && "JITDylib, but no MU?")((JITDylibAndMU.second && "JITDylib, but no MU?") ? static_cast
<void> (0) : __assert_fail ("JITDylibAndMU.second && \"JITDylib, but no MU?\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/Core.cpp"
, 2280, __PRETTY_FUNCTION__))
;
2281 dispatchMaterialization(*JITDylibAndMU.first,
2282 std::move(JITDylibAndMU.second));
2283 } else
2284 break;
2285 }
2286}
2287
2288} // End namespace orc.
2289} // End namespace llvm.

/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ADT/FunctionExtras.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.
15///
16/// Future plans:
17/// - Add a `function` that provides const, volatile, and ref-qualified support,
18/// which doesn't work 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_FUNCTION_EXTRAS_H
33#define LLVM_ADT_FUNCTION_EXTRAS_H
34
35#include "llvm/ADT/PointerIntPair.h"
36#include "llvm/ADT/PointerUnion.h"
37#include "llvm/Support/type_traits.h"
38#include <memory>
39
40namespace llvm {
41
42template <typename FunctionT> class unique_function;
43
44template <typename ReturnT, typename... ParamTs>
45class unique_function<ReturnT(ParamTs...)> {
46 static constexpr size_t InlineStorageSize = sizeof(void *) * 3;
47
48 // MSVC has a bug and ICEs if we give it a particular dependent value
49 // expression as part of the `std::conditional` below. To work around this,
50 // we build that into a template struct's constexpr bool.
51 template <typename T> struct IsSizeLessThanThresholdT {
52 static constexpr bool value = sizeof(T) <= (2 * sizeof(void *));
53 };
54
55 // Provide a type function to map parameters that won't observe extra copies
56 // or moves and which are small enough to likely pass in register to values
57 // and all other types to l-value reference types. We use this to compute the
58 // types used in our erased call utility to minimize copies and moves unless
59 // doing so would force things unnecessarily into memory.
60 //
61 // The heuristic used is related to common ABI register passing conventions.
62 // It doesn't have to be exact though, and in one way it is more strict
63 // because we want to still be able to observe either moves *or* copies.
64 template <typename T>
65 using AdjustedParamT = typename std::conditional<
66 !std::is_reference<T>::value &&
67 llvm::is_trivially_copy_constructible<T>::value &&
68 llvm::is_trivially_move_constructible<T>::value &&
69 IsSizeLessThanThresholdT<T>::value,
70 T, T &>::type;
71
72 // The type of the erased function pointer we use as a callback to dispatch to
73 // the stored callable when it is trivial to move and destroy.
74 using CallPtrT = ReturnT (*)(void *CallableAddr,
75 AdjustedParamT<ParamTs>... Params);
76 using MovePtrT = void (*)(void *LHSCallableAddr, void *RHSCallableAddr);
77 using DestroyPtrT = void (*)(void *CallableAddr);
78
79 /// A struct to hold a single trivial callback with sufficient alignment for
80 /// our bitpacking.
81 struct alignas(8) TrivialCallback {
82 CallPtrT CallPtr;
83 };
84
85 /// A struct we use to aggregate three callbacks when we need full set of
86 /// operations.
87 struct alignas(8) NonTrivialCallbacks {
88 CallPtrT CallPtr;
89 MovePtrT MovePtr;
90 DestroyPtrT DestroyPtr;
91 };
92
93 // Create a pointer union between either a pointer to a static trivial call
94 // pointer in a struct or a pointer to a static struct of the call, move, and
95 // destroy pointers.
96 using CallbackPointerUnionT =
97 PointerUnion<TrivialCallback *, NonTrivialCallbacks *>;
98
99 // The main storage buffer. This will either have a pointer to out-of-line
100 // storage or an inline buffer storing the callable.
101 union StorageUnionT {
102 // For out-of-line storage we keep a pointer to the underlying storage and
103 // the size. This is enough to deallocate the memory.
104 struct OutOfLineStorageT {
105 void *StoragePtr;
106 size_t Size;
107 size_t Alignment;
108 } OutOfLineStorage;
109 static_assert(
110 sizeof(OutOfLineStorageT) <= InlineStorageSize,
111 "Should always use all of the out-of-line storage for inline storage!");
112
113 // For in-line storage, we just provide an aligned character buffer. We
114 // provide three pointers worth of storage here.
115 typename std::aligned_storage<InlineStorageSize, alignof(void *)>::type
116 InlineStorage;
117 } StorageUnion;
118
119 // A compressed pointer to either our dispatching callback or our table of
120 // dispatching callbacks and the flag for whether the callable itself is
121 // stored inline or not.
122 PointerIntPair<CallbackPointerUnionT, 1, bool> CallbackAndInlineFlag;
123
124 bool isInlineStorage() const { return CallbackAndInlineFlag.getInt(); }
125
126 bool isTrivialCallback() const {
127 return CallbackAndInlineFlag.getPointer().template is<TrivialCallback *>();
128 }
129
130 CallPtrT getTrivialCallback() const {
131 return CallbackAndInlineFlag.getPointer().template get<TrivialCallback *>()->CallPtr;
132 }
133
134 NonTrivialCallbacks *getNonTrivialCallbacks() const {
135 return CallbackAndInlineFlag.getPointer()
136 .template get<NonTrivialCallbacks *>();
137 }
138
139 void *getInlineStorage() { return &StorageUnion.InlineStorage; }
140
141 void *getOutOfLineStorage() {
142 return StorageUnion.OutOfLineStorage.StoragePtr;
18
Undefined or garbage value returned to caller
143 }
144 size_t getOutOfLineStorageSize() const {
145 return StorageUnion.OutOfLineStorage.Size;
146 }
147 size_t getOutOfLineStorageAlignment() const {
148 return StorageUnion.OutOfLineStorage.Alignment;
149 }
150
151 void setOutOfLineStorage(void *Ptr, size_t Size, size_t Alignment) {
152 StorageUnion.OutOfLineStorage = {Ptr, Size, Alignment};
153 }
154
155 template <typename CallableT>
156 static ReturnT CallImpl(void *CallableAddr, AdjustedParamT<ParamTs>... Params) {
157 return (*reinterpret_cast<CallableT *>(CallableAddr))(
158 std::forward<ParamTs>(Params)...);
159 }
160
161 template <typename CallableT>
162 static void MoveImpl(void *LHSCallableAddr, void *RHSCallableAddr) noexcept {
163 new (LHSCallableAddr)
164 CallableT(std::move(*reinterpret_cast<CallableT *>(RHSCallableAddr)));
165 }
166
167 template <typename CallableT>
168 static void DestroyImpl(void *CallableAddr) noexcept {
169 reinterpret_cast<CallableT *>(CallableAddr)->~CallableT();
170 }
171
172public:
173 unique_function() = default;
174 unique_function(std::nullptr_t /*null_callable*/) {}
175
176 ~unique_function() {
177 if (!CallbackAndInlineFlag.getPointer())
178 return;
179
180 // Cache this value so we don't re-check it after type-erased operations.
181 bool IsInlineStorage = isInlineStorage();
182
183 if (!isTrivialCallback())
184 getNonTrivialCallbacks()->DestroyPtr(
185 IsInlineStorage ? getInlineStorage() : getOutOfLineStorage());
186
187 if (!IsInlineStorage)
188 deallocate_buffer(getOutOfLineStorage(), getOutOfLineStorageSize(),
189 getOutOfLineStorageAlignment());
190 }
191
192 unique_function(unique_function &&RHS) noexcept {
193 // Copy the callback and inline flag.
194 CallbackAndInlineFlag = RHS.CallbackAndInlineFlag;
195
196 // If the RHS is empty, just copying the above is sufficient.
197 if (!RHS)
11
Taking true branch
198 return;
12
Returning without writing to 'this->StorageUnion.OutOfLineStorage.StoragePtr'
199
200 if (!isInlineStorage()) {
201 // The out-of-line case is easiest to move.
202 StorageUnion.OutOfLineStorage = RHS.StorageUnion.OutOfLineStorage;
203 } else if (isTrivialCallback()) {
204 // Move is trivial, just memcpy the bytes across.
205 memcpy(getInlineStorage(), RHS.getInlineStorage(), InlineStorageSize);
206 } else {
207 // Non-trivial move, so dispatch to a type-erased implementation.
208 getNonTrivialCallbacks()->MovePtr(getInlineStorage(),
209 RHS.getInlineStorage());
210 }
211
212 // Clear the old callback and inline flag to get back to as-if-null.
213 RHS.CallbackAndInlineFlag = {};
214
215#ifndef NDEBUG
216 // In debug builds, we also scribble across the rest of the storage.
217 memset(RHS.getInlineStorage(), 0xAD, InlineStorageSize);
218#endif
219 }
220
221 unique_function &operator=(unique_function &&RHS) noexcept {
222 if (this == &RHS)
223 return *this;
224
225 // Because we don't try to provide any exception safety guarantees we can
226 // implement move assignment very simply by first destroying the current
227 // object and then move-constructing over top of it.
228 this->~unique_function();
229 new (this) unique_function(std::move(RHS));
230 return *this;
231 }
232
233 template <typename CallableT> unique_function(CallableT Callable) {
234 bool IsInlineStorage = true;
235 void *CallableAddr = getInlineStorage();
236 if (sizeof(CallableT) > InlineStorageSize ||
237 alignof(CallableT) > alignof(decltype(StorageUnion.InlineStorage))) {
238 IsInlineStorage = false;
239 // Allocate out-of-line storage. FIXME: Use an explicit alignment
240 // parameter in C++17 mode.
241 auto Size = sizeof(CallableT);
242 auto Alignment = alignof(CallableT);
243 CallableAddr = allocate_buffer(Size, Alignment);
244 setOutOfLineStorage(CallableAddr, Size, Alignment);
245 }
246
247 // Now move into the storage.
248 new (CallableAddr) CallableT(std::move(Callable));
249
250 // See if we can create a trivial callback. We need the callable to be
251 // trivially moved and trivially destroyed so that we don't have to store
252 // type erased callbacks for those operations.
253 //
254 // FIXME: We should use constexpr if here and below to avoid instantiating
255 // the non-trivial static objects when unnecessary. While the linker should
256 // remove them, it is still wasteful.
257 if (llvm::is_trivially_move_constructible<CallableT>::value &&
258 std::is_trivially_destructible<CallableT>::value) {
259 // We need to create a nicely aligned object. We use a static variable
260 // for this because it is a trivial struct.
261 static TrivialCallback Callback = { &CallImpl<CallableT> };
262
263 CallbackAndInlineFlag = {&Callback, IsInlineStorage};
264 return;
265 }
266
267 // Otherwise, we need to point at an object that contains all the different
268 // type erased behaviors needed. Create a static instance of the struct type
269 // here and then use a pointer to that.
270 static NonTrivialCallbacks Callbacks = {
271 &CallImpl<CallableT>, &MoveImpl<CallableT>, &DestroyImpl<CallableT>};
272
273 CallbackAndInlineFlag = {&Callbacks, IsInlineStorage};
274 }
275
276 ReturnT operator()(ParamTs... Params) {
277 void *CallableAddr =
278 isInlineStorage() ? getInlineStorage() : getOutOfLineStorage();
15
Assuming the condition is false
16
'?' condition is false
17
Calling 'unique_function::getOutOfLineStorage'
279
280 return (isTrivialCallback()
281 ? getTrivialCallback()
282 : getNonTrivialCallbacks()->CallPtr)(CallableAddr, Params...);
283 }
284
285 explicit operator bool() const {
286 return (bool)CallbackAndInlineFlag.getPointer();
287 }
288};
289
290} // end namespace llvm
291
292#endif // LLVM_ADT_FUNCTION_H