Skip to content

Commit ccfdb67

Browse files
committed
Eliminate deadlock in context descriptor cache
1 parent 648a837 commit ccfdb67

File tree

1 file changed

+15
-13
lines changed

1 file changed

+15
-13
lines changed

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -637,11 +637,11 @@ _scanAdditionalContextDescriptors(TypeMetadataPrivateState &T) {
637637
// Search for a ContextDescriptor in the context descriptor cache matching the
638638
// given demangle node. Returns the found node, or nullptr if no match was
639639
// found.
640-
static const ContextDescriptor *
640+
static llvm::TinyPtrVector<const ContextDescriptor *>
641641
_findContextDescriptorInCache(TypeMetadataPrivateState &T,
642642
Demangle::NodePointer node) {
643643
if (node->getNumChildren() < 2)
644-
return nullptr;
644+
return { };
645645

646646
auto nameNode = node->getChild(1);
647647

@@ -651,21 +651,15 @@ _findContextDescriptorInCache(TypeMetadataPrivateState &T,
651651
nameNode = nameNode->getChild(1);
652652

653653
if (nameNode->getKind() != Demangle::Node::Kind::Identifier)
654-
return nullptr;
654+
return { };
655655

656656
auto name = nameNode->getText();
657657

658658
auto iter = T.ContextDescriptorCache.find(name);
659659
if (iter == T.ContextDescriptorCache.end())
660-
return nullptr;
661-
662-
for (auto *contextDescriptor : iter->getSecond()) {
663-
if (_contextDescriptorMatchesMangling(contextDescriptor, node)) {
664-
return contextDescriptor;
665-
}
666-
}
667-
668-
return nullptr;
660+
return { };
661+
662+
return iter->getSecond();
669663
}
670664

671665
static const ContextDescriptor *
@@ -697,10 +691,18 @@ _findContextDescriptor(Demangle::NodePointer node,
697691

698692
// Scan any newly loaded images for context descriptors, then try the context
699693
// descriptor cache. This must be done with the cache's lock held.
694+
llvm::TinyPtrVector<const ContextDescriptor *> cachedContexts;
700695
{
701696
ScopedLock guard(T.ContextDescriptorCacheLock);
702697
_scanAdditionalContextDescriptors(T);
703-
foundContext = _findContextDescriptorInCache(T, node);
698+
cachedContexts = _findContextDescriptorInCache(T, node);
699+
}
700+
701+
for (auto cachedContext : cachedContexts) {
702+
if (_contextDescriptorMatchesMangling(cachedContext, node)) {
703+
foundContext = cachedContext;
704+
break;
705+
}
704706
}
705707

706708
// Check type metadata records

0 commit comments

Comments
 (0)