Skip to content

Commit 7eee8c0

Browse files
committed
[Distributed] Runtime: Cache previously requested accessible functions
1 parent 3f4c06e commit 7eee8c0

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

stdlib/public/runtime/AccessibleFunction.cpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,42 @@ struct AccessibleFunctionsSection {
4646
const AccessibleFunctionRecord *end() const { return End; }
4747
};
4848

49+
struct AccessibleFunctionCacheEntry {
50+
private:
51+
const char *Name;
52+
size_t NameLength;
53+
54+
const AccessibleFunctionRecord *Func;
55+
56+
public:
57+
AccessibleFunctionCacheEntry(llvm::StringRef name,
58+
const AccessibleFunctionRecord *func)
59+
: Func(func) {
60+
char *Name = reinterpret_cast<char *>(malloc(name.size()));
61+
memcpy(Name, name.data(), name.size());
62+
63+
this->Name = Name;
64+
this->NameLength = name.size();
65+
}
66+
67+
const AccessibleFunctionRecord *getFunction() const { return Func; }
68+
69+
bool matchesKey(llvm::StringRef name) {
70+
return name == llvm::StringRef{Name, NameLength};
71+
}
72+
73+
friend llvm::hash_code hash_value(const AccessibleFunctionCacheEntry &value) {
74+
return hash_value(llvm::StringRef{value.Name, value.NameLength});
75+
}
76+
77+
template <class... T>
78+
static size_t getExtraAllocationSize(T &&...ignored) {
79+
return 0;
80+
}
81+
};
82+
4983
struct AccessibleFunctionsState {
84+
ConcurrentReadableHashMap<AccessibleFunctionCacheEntry> Cache;
5085
ConcurrentReadableArray<AccessibleFunctionsSection> SectionsToScan;
5186

5287
AccessibleFunctionsState() {
@@ -78,3 +113,43 @@ void swift::addImageAccessibleFunctionsBlockCallback(const void *functions,
78113
Functions.get();
79114
addImageAccessibleFunctionsBlockCallbackUnsafe(functions, size);
80115
}
116+
117+
static const AccessibleFunctionRecord *
118+
_searchForFunctionRecord(AccessibleFunctionsState &S, llvm::StringRef name) {
119+
for (const auto &section : S.SectionsToScan.snapshot()) {
120+
for (auto &record : section) {
121+
auto recordName =
122+
swift::Demangle::makeSymbolicMangledNameStringRef(record.Name.get());
123+
if (recordName == name)
124+
return &record;
125+
}
126+
}
127+
return nullptr;
128+
}
129+
130+
static const AccessibleFunctionRecord *
131+
_findAccessibleFunction(llvm::StringRef name) {
132+
auto &S = Functions.get();
133+
134+
// Look for an existing entry.
135+
{
136+
auto snapshot = S.Cache.snapshot();
137+
if (auto E = snapshot.find(name))
138+
return E->getFunction();
139+
}
140+
141+
// If entry doesn't exist (either record doesn't exist, hasn't been loaded, or
142+
// requested yet), let's try to find it and add to the cache.
143+
144+
auto *function = _searchForFunctionRecord(S, name);
145+
if (function) {
146+
S.Cache.getOrInsert(
147+
name, [&](AccessibleFunctionCacheEntry *entry, bool created) {
148+
if (created)
149+
new (entry) AccessibleFunctionCacheEntry{name, function};
150+
return true;
151+
});
152+
}
153+
154+
return function;
155+
}

0 commit comments

Comments
 (0)