Skip to content

Commit 60b4f38

Browse files
Eliminate context descriptor cache (#29151)
1 parent 9b33ece commit 60b4f38

File tree

3 files changed

+9
-169
lines changed

3 files changed

+9
-169
lines changed

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 9 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -205,21 +205,10 @@ namespace {
205205
};
206206
} // end anonymous namespace
207207

208-
inline llvm::hash_code llvm::hash_value(StringRef S) {
209-
return hash_combine_range(S.begin(), S.end());
210-
}
211-
212208
struct TypeMetadataPrivateState {
213209
ConcurrentMap<NominalTypeDescriptorCacheEntry> NominalCache;
214210
ConcurrentReadableArray<TypeMetadataSection> SectionsToScan;
215211

216-
llvm::DenseMap<llvm::StringRef,
217-
llvm::SmallDenseSet<const ContextDescriptor *, 1>>
218-
ContextDescriptorCache;
219-
size_t ConformanceDescriptorLastSectionScanned = 0;
220-
size_t TypeContextDescriptorLastSectionScanned = 0;
221-
Mutex ContextDescriptorCacheLock;
222-
223212
TypeMetadataPrivateState() {
224213
initializeTypeMetadataRecordLookup();
225214
}
@@ -235,29 +224,6 @@ _registerTypeMetadataRecords(TypeMetadataPrivateState &T,
235224
T.SectionsToScan.push_back(TypeMetadataSection{begin, end});
236225
}
237226

238-
/// Iterate over type metadata sections starting from the given index.
239-
/// The index is updated to the current number of sections. Passing
240-
/// the same index to the next call will iterate over any sections that were
241-
/// added after the previous call.
242-
///
243-
/// Takes a function to call for each section found. The two parameters are
244-
/// the start and end of the section.
245-
static void _forEachTypeMetadataSectionAfter(
246-
TypeMetadataPrivateState &T,
247-
size_t *start,
248-
const std::function<void(const TypeMetadataRecord *,
249-
const TypeMetadataRecord *)> &f) {
250-
auto snapshot = T.SectionsToScan.snapshot();
251-
if (snapshot.Count > *start) {
252-
auto *begin = snapshot.begin() + *start;
253-
auto *end = snapshot.end();
254-
for (auto *section = begin; section != end; section++) {
255-
f(section->Begin, section->End);
256-
}
257-
*start = snapshot.Count;
258-
}
259-
}
260-
261227
void swift::addImageTypeMetadataRecordBlockCallbackUnsafe(
262228
const void *records, uintptr_t recordsSize) {
263229
assert(recordsSize % sizeof(TypeMetadataRecord) == 0
@@ -654,70 +620,6 @@ _searchTypeMetadataRecords(TypeMetadataPrivateState &T,
654620
return nullptr;
655621
}
656622

657-
// Read ContextDescriptors for any loaded images that haven't already been
658-
// scanned, if any.
659-
static void
660-
_scanAdditionalContextDescriptors(TypeMetadataPrivateState &T) {
661-
_forEachTypeMetadataSectionAfter(
662-
T,
663-
&T.TypeContextDescriptorLastSectionScanned,
664-
[&T](const TypeMetadataRecord *Begin,
665-
const TypeMetadataRecord *End) {
666-
for (const auto *record = Begin; record != End; record++) {
667-
if (auto ntd = record->getContextDescriptor()) {
668-
if (auto type = llvm::dyn_cast<TypeContextDescriptor>(ntd)) {
669-
auto identity = ParsedTypeIdentity::parse(type);
670-
auto name = identity.getABIName();
671-
T.ContextDescriptorCache[name].insert(type);
672-
}
673-
}
674-
}
675-
});
676-
677-
_forEachProtocolConformanceSectionAfter(
678-
&T.ConformanceDescriptorLastSectionScanned,
679-
[&T](const ProtocolConformanceRecord *Begin,
680-
const ProtocolConformanceRecord *End) {
681-
for (const auto *record = Begin; record != End; record++) {
682-
if (auto ntd = record[0]->getTypeDescriptor()) {
683-
if (auto type = llvm::dyn_cast<TypeContextDescriptor>(ntd)) {
684-
auto identity = ParsedTypeIdentity::parse(type);
685-
auto name = identity.getABIName();
686-
T.ContextDescriptorCache[name].insert(type);
687-
}
688-
}
689-
}
690-
});
691-
}
692-
693-
// Search for a ContextDescriptor in the context descriptor cache matching the
694-
// given demangle node. Returns the found node, or nullptr if no match was
695-
// found.
696-
static llvm::SmallDenseSet<const ContextDescriptor *, 1>
697-
_findContextDescriptorInCache(TypeMetadataPrivateState &T,
698-
Demangle::NodePointer node) {
699-
if (node->getNumChildren() < 2)
700-
return { };
701-
702-
auto nameNode = node->getChild(1);
703-
704-
// Declarations synthesized by the Clang importer get a small tag
705-
// string in addition to their name.
706-
if (nameNode->getKind() == Demangle::Node::Kind::RelatedEntityDeclName)
707-
nameNode = nameNode->getChild(1);
708-
709-
if (nameNode->getKind() != Demangle::Node::Kind::Identifier)
710-
return { };
711-
712-
auto name = nameNode->getText();
713-
714-
auto iter = T.ContextDescriptorCache.find(name);
715-
if (iter == T.ContextDescriptorCache.end())
716-
return { };
717-
718-
return iter->getSecond();
719-
}
720-
721623
#define DESCRIPTOR_MANGLING_SUFFIX_Structure Mn
722624
#define DESCRIPTOR_MANGLING_SUFFIX_Enum Mn
723625
#define DESCRIPTOR_MANGLING_SUFFIX_Protocol Mp
@@ -785,51 +687,18 @@ _findContextDescriptor(Demangle::NodePointer node,
785687
if (auto Value = T.NominalCache.find(mangledName))
786688
return Value->getDescription();
787689

690+
// Check type metadata records
788691
// Scan any newly loaded images for context descriptors, then try the context
789-
// descriptor cache. This must be done with the cache's lock held.
790-
llvm::SmallDenseSet<const ContextDescriptor *, 1> cachedContexts;
791-
{
792-
ScopedLock guard(T.ContextDescriptorCacheLock);
793-
_scanAdditionalContextDescriptors(T);
794-
cachedContexts = _findContextDescriptorInCache(T, node);
795-
}
796-
797-
bool foundInCache = false;
798-
for (auto cachedContext : cachedContexts) {
799-
if (_contextDescriptorMatchesMangling(cachedContext, node)) {
800-
foundContext = cachedContext;
801-
foundInCache = true;
802-
break;
803-
}
804-
}
805-
806-
if (!foundContext) {
807-
// Slow path, as a fallback if the cache itself isn't capturing everything.
808-
(void)foundInCache;
809-
810-
// Check type metadata records
811-
foundContext = _searchTypeMetadataRecords(T, node);
812-
813-
// Check protocol conformances table. Note that this has no support for
814-
// resolving generic types yet.
815-
if (!foundContext)
816-
foundContext = _searchConformancesByMangledTypeName(node);
817-
}
818-
819-
if (foundContext) {
692+
foundContext = _searchTypeMetadataRecords(T, node);
693+
694+
// Check protocol conformances table. Note that this has no support for
695+
// resolving generic types yet.
696+
if (!foundContext)
697+
foundContext = _searchConformancesByMangledTypeName(node);
698+
699+
if (foundContext)
820700
T.NominalCache.getOrInsert(mangledName, foundContext);
821701

822-
#ifndef NDEBUG
823-
// If we found something in the slow path but not in the cache, it is a
824-
// bug in the cache. Fail in assertions builds.
825-
if (!foundInCache) {
826-
fatalError(0,
827-
"_findContextDescriptor cache miss for demangled tree:\n%s\n",
828-
getNodeTreeAsString(node).c_str());
829-
}
830-
#endif
831-
}
832-
833702
return foundContext;
834703
}
835704

stdlib/public/runtime/Private.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -253,19 +253,6 @@ class TypeInfo {
253253
const ContextDescriptor *
254254
_searchConformancesByMangledTypeName(Demangle::NodePointer node);
255255

256-
/// Iterate over protocol conformance sections starting from the given index.
257-
/// The index is updated to the current number of protocol sections. Passing
258-
/// the same index to the next call will iterate over any sections that were
259-
/// added after the previous call.
260-
///
261-
/// Takes a function to call for each section found. The two parameters are
262-
/// the start and end of the section.
263-
void
264-
_forEachProtocolConformanceSectionAfter(
265-
size_t *start,
266-
const std::function<void(const ProtocolConformanceRecord *,
267-
const ProtocolConformanceRecord *)> &f);
268-
269256
Demangle::NodePointer _swift_buildDemanglingForMetadata(const Metadata *type,
270257
Demangle::Demangler &Dem);
271258

stdlib/public/runtime/ProtocolConformance.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -642,22 +642,6 @@ swift::_searchConformancesByMangledTypeName(Demangle::NodePointer node) {
642642
return nullptr;
643643
}
644644

645-
void
646-
swift::_forEachProtocolConformanceSectionAfter(
647-
size_t *start,
648-
const std::function<void(const ProtocolConformanceRecord *,
649-
const ProtocolConformanceRecord *)> &f) {
650-
auto snapshot = Conformances.get().SectionsToScan.snapshot();
651-
if (snapshot.Count > *start) {
652-
auto *begin = snapshot.begin() + *start;
653-
auto *end = snapshot.end();
654-
for (auto *section = begin; section != end; section++) {
655-
f(section->Begin, section->End);
656-
}
657-
*start = snapshot.Count;
658-
}
659-
}
660-
661645
bool swift::_checkGenericRequirements(
662646
llvm::ArrayRef<GenericRequirementDescriptor> requirements,
663647
SmallVectorImpl<const void *> &extraArguments,

0 commit comments

Comments
 (0)