14#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_LIBRARYRESOLVER_H
15#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_LIBRARYRESOLVER_H
23#include <shared_mutex>
38 std::optional<BloomFilter> Filter = std::nullopt)
39 : FilePath(
std::
move(FilePath)), S(S), K(K), Filter(
std::
move(Filter)) {}
47 std::lock_guard<std::shared_mutex> Lock(Mtx);
50 Filter.emplace(std::move(
F));
55 std::lock_guard<std::shared_mutex> Lock(Mtx);
58 Filter.emplace(FB.
build(Symbols));
63 std::shared_lock<std::shared_mutex> Lock(Mtx);
64 return Filter->mayContain(Symbol);
68 std::shared_lock<std::shared_mutex> Lock(Mtx);
69 return Filter.has_value();
78 return FilePath == other.FilePath;
83 std::atomic<LibState> S;
85 std::optional<BloomFilter>
Filter;
86 mutable std::shared_mutex Mtx;
99 while (Pos < Lists.size()) {
101 if (
Lib->getState() == S)
111 const std::vector<const LibraryInfo *> &Lists;
119 friend LibraryManager;
123 static std::vector<const LibraryInfo *>
Empty;
124 auto It = Lists.find(K);
125 if (It == Lists.end())
132 auto It = Lists.find(K);
133 if (It == Lists.end())
136 const auto &L = It->second;
137 return L.size() > Idx;
142 Lists[
Lib->getKind()].push_back(
Lib);
145 void clear() { Lists.clear(); }
147 DenseMap<PathType, std::vector<const LibraryInfo *>> Lists;
168 : it(it_), end(end_), S(S), K(K) {
173 return it != other.it;
186 for (; it !=
end; ++it)
187 if (it->second->getState() == S && it->second->getKind() == K)
196 : mapBegin(
begin), mapEnd(
end), state(s), kind(k) {}
216 mutable std::shared_mutex Mtx;
225 std::optional<BloomFilter>
Filter = std::nullopt) {
226 std::unique_lock<std::shared_mutex> Lock(Mtx);
227 if (Libraries.count(Path) > 0)
229 std::unique_ptr<LibraryInfo>
Lib = std::make_unique<LibraryInfo>(
232 Libraries.insert({Path, std::move(
Lib)});
233 Index.addLibrary(Ptr);
238 std::shared_lock<std::shared_mutex> Lock(Mtx);
239 if (Libraries.count(Path) > 0)
245 std::unique_lock<std::shared_mutex> Lock(Mtx);
246 auto I = Libraries.find(Path);
247 if (
I == Libraries.end())
253 std::unique_lock<std::shared_mutex> Lock(Mtx);
254 if (
auto It = Libraries.find(Path); It != Libraries.end())
259 std::unique_lock<std::shared_mutex> Lock(Mtx);
260 if (
auto It = Libraries.find(Path); It != Libraries.end())
265 std::unique_lock<std::shared_mutex> Lock(Mtx);
266 if (
auto It = Libraries.find(Path); It != Libraries.end())
271 std::shared_lock<std::shared_mutex> Lock(Mtx);
272 if (
auto It = Libraries.find(Path); It != Libraries.end())
273 return It->second.get();
278 std::shared_lock<std::shared_mutex> Lock(Mtx);
279 return FilteredView(Libraries.begin(), Libraries.end(), S, K);
284 std::vector<const LibraryInfo *> &Outs,
286 std::shared_lock<std::shared_mutex> Lock(Mtx);
287 for (
const auto &[
_, Entry] : Libraries) {
288 const auto &
Info = *Entry;
289 if (
Info.getKind() != K ||
Info.getState() != S)
293 Outs.push_back(&
Info);
298 return Index.getCursor(K, S);
302 std::shared_lock<std::shared_mutex> Lock(Mtx);
303 for (
const auto &[
_, entry] : Libraries) {
304 if (!visitor(*entry))
310 std::shared_lock<std::shared_mutex> Lock(Mtx);
311 if (
auto It = Libraries.find(Path.str()); It != Libraries.end())
317 std::shared_lock<std::shared_mutex> Lock(Mtx);
318 if (
auto It = Libraries.find(Path.str()); It != Libraries.end())
324 std::unique_lock<std::shared_mutex> Lock(Mtx);
335 std::vector<SearchPlanEntry>
Plan;
409 mutable std::shared_mutex Mtx;
411 std::atomic<size_t> ResolvedCount = 0;
415 for (
const auto &S : Symbols) {
417 Entries.push_back({S.str(),
""});
423 [&](
const Entry &
E) {
return E.Name == Name; });
429 std::shared_lock<std::shared_mutex> Lock(Mtx);
430 for (
const auto &
E : Entries) {
431 if (
E.ResolvedLibPath.empty() && Allow(
E.Name))
437 std::unique_lock<std::shared_mutex> Lock(Mtx);
438 for (
auto &
E : Entries) {
439 if (
E.Name == Sym &&
E.ResolvedLibPath.empty()) {
440 E.ResolvedLibPath = LibPath;
441 ResolvedCount.fetch_add(1, std::memory_order_relaxed);
448 return ResolvedCount.load(std::memory_order_relaxed) == Entries.size();
452 return ResolvedCount.load(std::memory_order_relaxed) < Entries.size();
456 std::shared_lock<std::shared_mutex> Lock(Mtx);
457 for (
const auto &
E : Entries)
458 if (
E.Name == Sym && !
E.ResolvedLibPath.empty())
459 return E.ResolvedLibPath;
464 std::shared_lock<std::shared_mutex> Lock(Mtx);
465 for (
const auto &
E : Entries)
466 if (
E.Name == Sym && !
E.ResolvedLibPath.empty())
472 std::shared_lock<std::shared_mutex> Lock(Mtx);
473 std::vector<const Entry *> Out;
474 Out.reserve(Entries.size());
475 for (
const auto &
E : Entries)
510 if (customShouldScan)
526 dbgs() << ++i <<
". Library Path : " <<
Lib.getFullPath() <<
" -> \n\t\t:"
528 << (
Lib.getKind() == PathType::User ?
"User" :
"System")
541 bool scanLibrariesIfNeeded(
PathType K,
size_t BatchSize = 0);
547 std::shared_ptr<LibraryPathCache> LibPathCache;
548 std::shared_ptr<PathResolver> LibPathResolver;
552 size_t scanBatchSize;
559class LibraryResolutionDriver {
561 static std::unique_ptr<LibraryResolutionDriver>
568 return LR->LibMgr.isLoaded(Path);
573 LR->ScanHelper.resetToScan();
574 LR->LibPathCache->clear();
578 LR->scanLibrariesIfNeeded(PathType::User, BatchSize);
579 LR->scanLibrariesIfNeeded(PathType::System, BatchSize);
583 LR->scanLibrariesIfNeeded(PK, BatchSize);
593 LibraryResolutionDriver(std::unique_ptr<LibraryResolver> L)
596 std::unique_ptr<LibraryResolver> LR;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
LocallyHashedType DenseMapInfo< LocallyHashedType >::Empty
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
StringMapIterBase< std::unique_ptr< LibraryInfo >, true > const_iterator
StringRef - Represent a constant reference to a string, i.e.
This class is the base class for all object file types.
BloomFilter build(ArrayRef< StringRef > Symbols) const
LibraryCursor(const std::vector< const LibraryInfo * > &L, LibState S)
bool hasMoreValidLib() const
const LibraryInfo * nextValidLib()
LibraryCursor getCursor(PathType K, LibState S) const
bool hasLibLeftFor(PathType K, uint32_t Idx) const
LibraryInfo & operator=(const LibraryInfo &)=delete
void setState(LibState s)
bool operator==(const LibraryInfo &other) const
bool mayContain(StringRef Symbol) const
std::string getFullPath() const
StringRef getBasePath() const
void setFilter(BloomFilter F)
StringRef getFileName() const
void ensureFilterBuilt(const BloomFilterBuilder &FB, ArrayRef< StringRef > Symbols)
LibraryInfo(const LibraryInfo &)=delete
LibState getState() const
LibraryInfo(std::string FilePath, LibState S, PathType K, std::optional< BloomFilter > Filter=std::nullopt)
bool operator!=(const FilterIterator &other) const
const LibraryInfo & operator*() const
FilterIterator & operator++()
FilterIterator(Iterator it_, Iterator end_, LibState S, PathType K)
A read-only view of libraries filtered by state and kind.
StringMap< std::unique_ptr< LibraryInfo > > Map
Map::const_iterator Iterator
FilterIterator begin() const
FilteredView(Iterator begin, Iterator end, LibState s, PathType k)
FilterIterator end() const
Manages library metadata and state for symbol resolution.
bool hasLibrary(StringRef Path) const
bool isLoaded(StringRef Path) const
void markLoaded(StringRef Path)
FilteredView getView(LibState S, PathType K) const
void markUnloaded(StringRef Path)
void removeLibrary(StringRef Path)
void forEachLibrary(const LibraryVisitor &visitor) const
const LibraryInfo * getLibrary(StringRef Path) const
std::function< bool(const LibraryInfo &)> LibraryFilterFn
std::function< bool(const LibraryInfo &)> LibraryVisitor
void getLibraries(LibState S, PathType K, std::vector< const LibraryInfo * > &Outs, LibraryFilterFn Filter=nullptr) const
bool addLibrary(std::string Path, PathType Kind, std::optional< BloomFilter > Filter=std::nullopt)
bool isQueried(StringRef Path) const
~LibraryManager()=default
void markQueried(StringRef Path)
LibraryCursor getCursor(PathType K, LibState S) const
void resolveSymbols(ArrayRef< StringRef > Symbols, LibraryResolver::OnSearchComplete OnCompletion, const SearchConfig &Config=SearchConfig())
void addScanPath(const std::string &Path, PathType Kind)
void markLibraryUnLoaded(StringRef Path)
~LibraryResolutionDriver()=default
void markLibraryLoaded(StringRef Path)
void scan(PathType PK, size_t BatchSize=0)
void scanAll(size_t BatchSize=0)
bool isLibraryLoaded(StringRef Path) const
static std::unique_ptr< LibraryResolutionDriver > create(const LibraryResolver::Setup &S)
std::function< EnumerateResult(StringRef Sym)> OnEachSymbolFn
static bool enumerateSymbols(object::ObjectFile *Obj, OnEachSymbolFn OnEach, const SymbolEnumeratorOptions &Opts)
Tracks a set of symbols and the libraries where they are resolved.
bool contains(StringRef Name) const
std::optional< StringRef > getResolvedLib(StringRef Sym) const
bool hasUnresolved() const
SymbolQuery(ArrayRef< StringRef > Symbols)
unique_function< bool(StringRef)> SymbolFilterFn
void getUnresolvedSymbols(SmallVectorImpl< StringRef > &Unresolved, SymbolFilterFn Allow) const
std::vector< const Entry * > getAllResults() const
bool isResolved(StringRef Sym) const
void resolve(StringRef Sym, const std::string &LibPath)
~LibraryResolver()=default
unique_function< void(SymbolQuery &)> OnSearchComplete
friend class LibraryResolutionDriver
void searchSymbolsInLibraries(ArrayRef< StringRef > SymList, OnSearchComplete OnComplete, const SearchConfig &Config=SearchConfig())
Scans and tracks libraries for symbol resolution.
std::function< bool(StringRef)> ShouldScanFn
unique_function is a type-erasing functor similar to std::function.
SymbolEnumerator::EnumerateResult EnumerateResult
LibraryResolver::SymbolEnumerator SymbolEnumerator
LibraryResolver::SymbolQuery SymbolQuery
LLVM_ABI StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
This is an optimization pass for GlobalISel generic memory operations.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.
BloomFilterBuilder FilterBuilder
LibraryScanner::ShouldScanFn ShouldScanCall
static Setup create(std::vector< std::string > BasePaths, LibraryScanner::ShouldScanFn customShouldScan=nullptr)
std::vector< std::string > BasePaths
Holds the result for a single symbol.
std::string ResolvedLibPath
SymbolEnumeratorOptions Options
static SearchPolicy defaultPlan()
std::vector< SearchPlanEntry > Plan
static SymbolEnumeratorOptions defaultOptions()