Skip to content

[5.9][Runtime] Fast-path lookup of protocol descriptors with standard manglings. #66961

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 30 additions & 17 deletions stdlib/public/runtime/MetadataLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -782,19 +782,11 @@ _searchTypeMetadataRecords(TypeMetadataPrivateState &T,

static const ConcurrencyStandardTypeDescriptors *concurrencyDescriptors;

/// Perform a fast-path lookup for standard library type references with short
/// manglings. Returns the appropriate descriptor, or NULL if the descriptor
/// couldn't be resolved, or if the node does not refer to one of those types.
static const ContextDescriptor *
_findContextDescriptor(Demangle::NodePointer node,
Demangle::Demangler &Dem) {
NodePointer symbolicNode = node;
if (symbolicNode->getKind() == Node::Kind::Type)
symbolicNode = symbolicNode->getChild(0);

// If we have a symbolic reference to a context, resolve it immediately.
if (symbolicNode->getKind() == Node::Kind::TypeSymbolicReference) {
return cast<TypeContextDescriptor>(
(const ContextDescriptor *)symbolicNode->getIndex());
}

descriptorFromStandardMangling(Demangle::NodePointer symbolicNode) {
#if SWIFT_STDLIB_SHORT_MANGLING_LOOKUPS
// Fast-path lookup for standard library type references with short manglings.
if (symbolicNode->getNumChildren() >= 2
Expand All @@ -820,6 +812,24 @@ _findContextDescriptor(Demangle::NodePointer node,
#include "swift/Demangling/StandardTypesMangling.def"
}
#endif
return nullptr;
}

static const ContextDescriptor *
_findContextDescriptor(Demangle::NodePointer node,
Demangle::Demangler &Dem) {
NodePointer symbolicNode = node;
if (symbolicNode->getKind() == Node::Kind::Type)
symbolicNode = symbolicNode->getChild(0);

// If we have a symbolic reference to a context, resolve it immediately.
if (symbolicNode->getKind() == Node::Kind::TypeSymbolicReference) {
return cast<TypeContextDescriptor>(
(const ContextDescriptor *)symbolicNode->getIndex());
}

if (auto *standardDescriptor = descriptorFromStandardMangling(symbolicNode))
return standardDescriptor;

const ContextDescriptor *foundContext = nullptr;
auto &T = TypeMetadataRecords.get();
Expand Down Expand Up @@ -984,8 +994,7 @@ _searchProtocolRecords(ProtocolMetadataPrivateState &C,

static const ProtocolDescriptor *
_findProtocolDescriptor(NodePointer node,
Demangle::Demangler &Dem,
std::string &mangledName) {
Demangle::Demangler &Dem) {
const ProtocolDescriptor *foundProtocol = nullptr;
auto &T = Protocols.get();

Expand All @@ -997,13 +1006,18 @@ _findProtocolDescriptor(NodePointer node,
return cast<ProtocolDescriptor>(
(const ContextDescriptor *)symbolicNode->getIndex());

if (auto *standardDescriptor = descriptorFromStandardMangling(symbolicNode)) {
assert(standardDescriptor->getKind() == ContextDescriptorKind::Protocol);
return static_cast<const ProtocolDescriptor *>(standardDescriptor);
}

auto mangling =
Demangle::mangleNode(node, ExpandResolvedSymbolicReferences(Dem), Dem);

if (!mangling.isSuccess())
return nullptr;

mangledName = mangling.result().str();
auto mangledName = mangling.result().str();

// Look for an existing entry.
// Find the bucket for the metadata entry.
Expand Down Expand Up @@ -1613,8 +1627,7 @@ class DecodedMetadataBuilder {

BuiltProtocolDecl createProtocolDecl(NodePointer node) const {
// Look for a protocol descriptor based on its mangled name.
std::string mangledName;
if (auto protocol = _findProtocolDescriptor(node, demangler, mangledName))
if (auto protocol = _findProtocolDescriptor(node, demangler))
return ProtocolDescriptorRef::forSwift(protocol);;

#if SWIFT_OBJC_INTEROP
Expand Down