mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Simplify and optimize the structural type metadata caches to use ConcurrentMap directly.
Previously, these were all using MetadataCache. MetadataCache is a more heavyweight structure which acquires a lock before building the metadata. This is appropriate if building the metadata is very expensive or might have semantic side-effects which cannot be rolled back. It's also useful when there's a risk of re-entrance, since it can diagnose such things instead of simply dead-locking or infinitely recursing. However, it's necessary for structural cases like tuple and function types, and instead we can just use ConcurrentMap, which does a compare-and-swap to publish the constructed metadata and potentially destroys it if another thread successfully won the race. This is an optimization which we could not previously attempt. As part of this, fix tuple metadata uniquing to consider the label string correctly. This exposes a bug where the runtime demangling of tuple metadata nodes doesn't preserve labels; fix this as well.
This commit is contained in:
@@ -209,10 +209,35 @@ Demangle::NodePointer swift::_swift_buildDemanglingForMetadata(const Metadata *t
|
||||
}
|
||||
case MetadataKind::Tuple: {
|
||||
auto tuple = static_cast<const TupleTypeMetadata *>(type);
|
||||
const char *labels = tuple->Labels;
|
||||
auto tupleNode = NodeFactory::create(Node::Kind::NonVariadicTuple);
|
||||
for (unsigned i = 0, e = tuple->NumElements; i < e; ++i) {
|
||||
auto elt = _swift_buildDemanglingForMetadata(tuple->getElement(i).Type);
|
||||
tupleNode->addChild(elt);
|
||||
auto elt = NodeFactory::create(Node::Kind::TupleElement);
|
||||
|
||||
// Add a label child if applicable:
|
||||
if (labels) {
|
||||
// Look for the next space in the labels string.
|
||||
if (const char *space = strchr(labels, ' ')) {
|
||||
// If there is one, and the label isn't empty, add a label child.
|
||||
if (labels != space) {
|
||||
auto eltName =
|
||||
NodeFactory::create(Node::Kind::TupleElementName,
|
||||
std::string(labels, space));
|
||||
elt->addChild(std::move(eltName));
|
||||
}
|
||||
|
||||
// Skip past the space.
|
||||
labels = space + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the element type child.
|
||||
auto eltType =
|
||||
_swift_buildDemanglingForMetadata(tuple->getElement(i).Type);
|
||||
elt->addChild(std::move(eltType));
|
||||
|
||||
// Add the completed element to the tuple.
|
||||
tupleNode->addChild(std::move(elt));
|
||||
}
|
||||
return tupleNode;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user