From 7d3a4b1c0c1c9e132a17eca80b05c709efb2007e Mon Sep 17 00:00:00 2001 From: Joe Groff Date: Mon, 13 Jul 2020 14:02:26 -0700 Subject: [PATCH] IRGen: Name the symbol for the private use area attached to protocol conformance descriptors. Make it easier to track the memory usage of these symbols. --- docs/ABI/Mangling.rst | 2 ++ include/swift/Demangling/DemangleNodes.def | 3 +++ lib/Demangling/Demangler.cpp | 3 +++ lib/Demangling/NodePrinter.cpp | 5 +++++ lib/Demangling/OldRemangler.cpp | 3 +++ lib/Demangling/Remangler.cpp | 5 +++++ lib/IRGen/GenProto.cpp | 7 ++++++- lib/IRGen/IRGenMangler.cpp | 17 +++++++++++++++++ lib/IRGen/IRGenMangler.h | 6 ++++-- .../IRGen/protocol_resilience_descriptors.swift | 2 +- 10 files changed, 49 insertions(+), 4 deletions(-) diff --git a/docs/ABI/Mangling.rst b/docs/ABI/Mangling.rst index d21ca5334d30a..591f24aa62f6f 100644 --- a/docs/ABI/Mangling.rst +++ b/docs/ABI/Mangling.rst @@ -171,6 +171,8 @@ Globals global ::= entity 'Wvd' // field offset global ::= entity 'WC' // resilient enum tag index + global ::= global 'MK' // instantiation cache associated with global + A direct symbol resolves directly to the address of an object. An indirect symbol resolves to the address of a pointer to the object. They are distinct manglings to make a certain class of bugs diff --git a/include/swift/Demangling/DemangleNodes.def b/include/swift/Demangling/DemangleNodes.def index 5e534c3e901fe..1db1736958c7b 100644 --- a/include/swift/Demangling/DemangleNodes.def +++ b/include/swift/Demangling/DemangleNodes.def @@ -291,5 +291,8 @@ CONTEXT_NODE(OpaqueReturnTypeOf) NODE(CanonicalSpecializedGenericMetaclass) NODE(CanonicalSpecializedGenericTypeMetadataAccessFunction) +// Added in Swift 5.4 +NODE(MetadataInstantiationCache) + #undef CONTEXT_NODE #undef NODE diff --git a/lib/Demangling/Demangler.cpp b/lib/Demangling/Demangler.cpp index e87f9f6bf691a..f554359b6e3c0 100644 --- a/lib/Demangling/Demangler.cpp +++ b/lib/Demangling/Demangler.cpp @@ -1911,6 +1911,9 @@ NodePointer Demangler::demangleMetatype() { case 'j': return createWithChild(Node::Kind::OpaqueTypeDescriptorAccessorKey, popNode()); + case 'K': + return createWithChild(Node::Kind::MetadataInstantiationCache, + popNode()); case 'k': return createWithChild(Node::Kind::OpaqueTypeDescriptorAccessorVar, popNode()); diff --git a/lib/Demangling/NodePrinter.cpp b/lib/Demangling/NodePrinter.cpp index b6e120722d13c..207855be586dc 100644 --- a/lib/Demangling/NodePrinter.cpp +++ b/lib/Demangling/NodePrinter.cpp @@ -454,6 +454,7 @@ class NodePrinter { case Node::Kind::PropertyDescriptor: case Node::Kind::ProtocolConformance: case Node::Kind::ProtocolConformanceDescriptor: + case Node::Kind::MetadataInstantiationCache: case Node::Kind::ProtocolDescriptor: case Node::Kind::ProtocolRequirementsBaseDescriptor: case Node::Kind::ProtocolSelfConformanceDescriptor: @@ -2433,6 +2434,10 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) { Printer << "canonical specialized generic type metadata accessor for "; print(Node->getChild(0)); return nullptr; + case Node::Kind::MetadataInstantiationCache: + Printer << "metadata instantiation cache for "; + print(Node->getChild(0)); + return nullptr; } printer_unreachable("bad node kind!"); } diff --git a/lib/Demangling/OldRemangler.cpp b/lib/Demangling/OldRemangler.cpp index 67aa6ba5c1e40..a0d81c77d6ec8 100644 --- a/lib/Demangling/OldRemangler.cpp +++ b/lib/Demangling/OldRemangler.cpp @@ -2132,6 +2132,9 @@ void Remangler::mangleOpaqueTypeDescriptorAccessorVar(Node *node) { void Remangler::mangleAccessorFunctionReference(Node *node) { unreachable("can't remangle"); } +void Remangler::mangleMetadataInstantiationCache(Node *node) { + unreachable("unsupported"); +} void Remangler::mangleCanonicalSpecializedGenericMetaclass(Node *node) { Buffer << "MM"; diff --git a/lib/Demangling/Remangler.cpp b/lib/Demangling/Remangler.cpp index 1af12dc3c93e5..85a9358c5ec29 100644 --- a/lib/Demangling/Remangler.cpp +++ b/lib/Demangling/Remangler.cpp @@ -2547,6 +2547,11 @@ void Remangler::mangleCanonicalSpecializedGenericTypeMetadataAccessFunction( Buffer << "Mb"; } +void Remangler::mangleMetadataInstantiationCache(Node *node) { + mangleSingleChildNode(node); + Buffer << "MK"; +} + } // anonymous namespace /// The top-level interface to the remangler. diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp index 3e7d81c2ca5fd..2795553485a5a 100644 --- a/lib/IRGen/GenProto.cpp +++ b/lib/IRGen/GenProto.cpp @@ -1924,11 +1924,16 @@ namespace { llvm::ArrayType::get(IGM.Int8PtrTy, swift::NumGenericMetadataPrivateDataWords); auto privateDataInit = llvm::Constant::getNullValue(privateDataTy); + + IRGenMangler mangler; + auto symbolName = + mangler.mangleProtocolConformanceInstantiationCache(Conformance); + auto privateData = new llvm::GlobalVariable(IGM.Module, privateDataTy, /*constant*/ false, llvm::GlobalVariable::InternalLinkage, - privateDataInit, ""); + privateDataInit, symbolName); B.addRelativeAddress(privateData); } } diff --git a/lib/IRGen/IRGenMangler.cpp b/lib/IRGen/IRGenMangler.cpp index e83e186519ed2..720a85ecc9887 100644 --- a/lib/IRGen/IRGenMangler.cpp +++ b/lib/IRGen/IRGenMangler.cpp @@ -143,6 +143,8 @@ IRGenMangler::mangleTypeForReflection(IRGenModule &IGM, }); } + + std::string IRGenMangler::mangleProtocolConformanceDescriptor( const RootProtocolConformance *conformance) { beginMangling(); @@ -157,6 +159,21 @@ std::string IRGenMangler::mangleProtocolConformanceDescriptor( return finalize(); } +std::string IRGenMangler::mangleProtocolConformanceInstantiationCache( + const RootProtocolConformance *conformance) { + beginMangling(); + if (isa(conformance)) { + appendProtocolConformance(conformance); + appendOperator("Mc"); + } else { + auto protocol = cast(conformance)->getProtocol(); + appendProtocolName(protocol); + appendOperator("MS"); + } + appendOperator("MK"); + return finalize(); +} + SymbolicMangling IRGenMangler::mangleProtocolConformanceForReflection(IRGenModule &IGM, Type ty, ProtocolConformanceRef conformance) { diff --git a/lib/IRGen/IRGenMangler.h b/lib/IRGen/IRGenMangler.h index 98e29b27bcb5f..7eab0485352b7 100644 --- a/lib/IRGen/IRGenMangler.h +++ b/lib/IRGen/IRGenMangler.h @@ -315,8 +315,10 @@ class IRGenMangler : public Mangle::ASTMangler { } std::string mangleProtocolConformanceDescriptor( - const RootProtocolConformance *conformance); - + const RootProtocolConformance *conformance); + std::string mangleProtocolConformanceInstantiationCache( + const RootProtocolConformance *conformance); + std::string manglePropertyDescriptor(const AbstractStorageDecl *storage) { beginMangling(); appendEntity(storage); diff --git a/test/IRGen/protocol_resilience_descriptors.swift b/test/IRGen/protocol_resilience_descriptors.swift index cc652d276ef26..69b7bbfcc92a5 100644 --- a/test/IRGen/protocol_resilience_descriptors.swift +++ b/test/IRGen/protocol_resilience_descriptors.swift @@ -69,7 +69,7 @@ public struct Y { } // -- instantiator function // CHECK-USAGE-SAME: i32 0, // -- private data area -// CHECK-USAGE-SAME: {{@[0-9]+}} +// CHECK-USAGE-SAME: "$s31protocol_resilience_descriptors1YV010resilient_A022OtherResilientProtocolAAMcMK" // -- // CHECK-USAGE-SAME: } extension Y: OtherResilientProtocol { }