Skip to content

Commit 5204af3

Browse files
Merge pull request swiftlang#30089 from nate-chandler/generic-metadata-prespecialization-components/classes
[metadata prespecialization] Support for classes.
2 parents 8c70a96 + bdef1ce commit 5204af3

File tree

50 files changed

+6459
-303
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+6459
-303
lines changed

include/swift/ABI/Metadata.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1025,7 +1025,7 @@ struct TargetAnyClassMetadata : public TargetHeapMetadata<Runtime> {
10251025
using TargetMetadata<Runtime>::setClassISA;
10261026
#endif
10271027

1028-
// Note that ObjC classes does not have a metadata header.
1028+
// Note that ObjC classes do not have a metadata header.
10291029

10301030
/// The metadata for the superclass. This is null for the root class.
10311031
ConstTargetMetadataPointer<Runtime, swift::TargetClassMetadata> Superclass;

include/swift/AST/Types.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,17 @@ class alignas(1 << TypeAlignInBits) TypeBase {
852852
/// \returns The superclass of this type, or a null type if it has no
853853
/// superclass.
854854
Type getSuperclass(bool useArchetypes = true);
855-
855+
856+
/// Retrieve the root class of this type by repeatedly retrieving the
857+
/// superclass.
858+
///
859+
/// \param useArchetypes Whether to use context archetypes for outer generic
860+
/// parameters if the class is nested inside a generic function.
861+
///
862+
/// \returns The base class of this type, or this type itself if it has no
863+
/// superclasses.
864+
Type getRootClass(bool useArchetypes = true);
865+
856866
/// True if this type is the exact superclass of another type.
857867
///
858868
/// \param ty The potential subclass.

include/swift/Demangling/DemangleNodes.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,5 +287,9 @@ NODE(OpaqueTypeDescriptorAccessorVar)
287287
NODE(OpaqueReturnType)
288288
CONTEXT_NODE(OpaqueReturnTypeOf)
289289

290+
// Added in Swift 5.3
291+
NODE(CanonicalSpecializedGenericMetaclass)
292+
NODE(CanonicalSpecializedGenericTypeMetadataAccessFunction)
293+
290294
#undef CONTEXT_NODE
291295
#undef NODE

include/swift/IRGen/Linking.h

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ class LinkEntity {
193193
/// The nominal type descriptor for a nominal type.
194194
/// The pointer is a NominalTypeDecl*.
195195
NominalTypeDescriptor,
196-
196+
197197
/// The descriptor for an opaque type.
198198
/// The pointer is an OpaqueTypeDecl*.
199199
OpaqueTypeDescriptor,
@@ -295,12 +295,12 @@ class LinkEntity {
295295
/// The descriptor for an extension.
296296
/// The pointer is an ExtensionDecl*.
297297
ExtensionDescriptor,
298-
298+
299299
/// The descriptor for a runtime-anonymous context.
300300
/// The pointer is the DeclContext* of a child of the context that should
301301
/// be considered private.
302302
AnonymousDescriptor,
303-
303+
304304
/// A SIL global variable. The pointer is a SILGlobalVariable*.
305305
SILGlobalVariable,
306306

@@ -384,6 +384,15 @@ class LinkEntity {
384384

385385
/// A global function pointer for dynamically replaceable functions.
386386
DynamicallyReplaceableFunctionVariable,
387+
388+
/// A reference to a metaclass-stub for a statically specialized generic
389+
/// class.
390+
/// The pointer is a canonical TypeBase*.
391+
CanonicalSpecializedGenericSwiftMetaclassStub,
392+
393+
/// An access function for prespecialized type metadata.
394+
/// The pointer is a canonical TypeBase*.
395+
CanonicalSpecializedGenericTypeMetadataAccessFunction,
387396
};
388397
friend struct llvm::DenseMapInfo<LinkEntity>;
389398

@@ -1020,6 +1029,22 @@ class LinkEntity {
10201029
return entity;
10211030
}
10221031

1032+
static LinkEntity
1033+
forSpecializedGenericSwiftMetaclassStub(CanType concreteType) {
1034+
LinkEntity entity;
1035+
entity.setForType(Kind::CanonicalSpecializedGenericSwiftMetaclassStub,
1036+
concreteType);
1037+
return entity;
1038+
}
1039+
1040+
static LinkEntity
1041+
forPrespecializedTypeMetadataAccessFunction(CanType theType) {
1042+
LinkEntity entity;
1043+
entity.setForType(
1044+
Kind::CanonicalSpecializedGenericTypeMetadataAccessFunction, theType);
1045+
return entity;
1046+
}
1047+
10231048
void mangle(llvm::raw_ostream &out) const;
10241049
void mangle(SmallVectorImpl<char> &buffer) const;
10251050
std::string mangleAsString() const;

lib/AST/Type.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,6 +1552,17 @@ Type TypeBase::getSuperclass(bool useArchetypes) {
15521552
return superclassTy.subst(subMap);
15531553
}
15541554

1555+
Type TypeBase::getRootClass(bool useArchetypes) {
1556+
Type iterator = this;
1557+
assert(iterator);
1558+
1559+
while (auto superclass = iterator->getSuperclass(useArchetypes)) {
1560+
iterator = superclass;
1561+
}
1562+
1563+
return iterator;
1564+
}
1565+
15551566
bool TypeBase::isExactSuperclassOf(Type ty) {
15561567
// For there to be a superclass relationship, we must be a class, and
15571568
// the potential subtype must be a class, superclass-bounded archetype,

lib/Demangling/Demangler.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1874,6 +1874,9 @@ NodePointer Demangler::demangleMetatype() {
18741874
case 'A':
18751875
return createWithChild(Node::Kind::ReflectionMetadataAssocTypeDescriptor,
18761876
popProtocolConformance());
1877+
case 'b':
1878+
return createWithPoppedType(
1879+
Node::Kind::CanonicalSpecializedGenericTypeMetadataAccessFunction);
18771880
case 'B':
18781881
return createWithChild(Node::Kind::ReflectionMetadataBuiltinDescriptor,
18791882
popNode(Node::Kind::Type));
@@ -1917,6 +1920,9 @@ NodePointer Demangler::demangleMetatype() {
19171920
return createWithPoppedType(Node::Kind::TypeMetadataLazyCache);
19181921
case 'm':
19191922
return createWithPoppedType(Node::Kind::Metaclass);
1923+
case 'M':
1924+
return createWithPoppedType(
1925+
Node::Kind::CanonicalSpecializedGenericMetaclass);
19201926
case 'n':
19211927
return createWithPoppedType(Node::Kind::NominalTypeDescriptor);
19221928
case 'o':

lib/Demangling/NodePrinter.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,8 @@ class NodePrinter {
540540
case Node::Kind::OpaqueTypeDescriptorSymbolicReference:
541541
case Node::Kind::OpaqueReturnType:
542542
case Node::Kind::OpaqueReturnTypeOf:
543+
case Node::Kind::CanonicalSpecializedGenericMetaclass:
544+
case Node::Kind::CanonicalSpecializedGenericTypeMetadataAccessFunction:
543545
return false;
544546
}
545547
printer_unreachable("bad node kind");
@@ -2418,6 +2420,14 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
24182420
case Node::Kind::AccessorFunctionReference:
24192421
Printer << "accessor function at " << Node->getIndex();
24202422
return nullptr;
2423+
case Node::Kind::CanonicalSpecializedGenericMetaclass:
2424+
Printer << "specialized generic metaclass for ";
2425+
print(Node->getFirstChild());
2426+
return nullptr;
2427+
case Node::Kind::CanonicalSpecializedGenericTypeMetadataAccessFunction:
2428+
Printer << "canonical specialized generic type metadata accessor for ";
2429+
print(Node->getChild(0));
2430+
return nullptr;
24212431
}
24222432
printer_unreachable("bad node kind!");
24232433
}

lib/Demangling/OldRemangler.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2133,6 +2133,17 @@ void Remangler::mangleAccessorFunctionReference(Node *node) {
21332133
unreachable("can't remangle");
21342134
}
21352135

2136+
void Remangler::mangleCanonicalSpecializedGenericMetaclass(Node *node) {
2137+
Buffer << "MM";
2138+
mangleSingleChildNode(node); // type
2139+
}
2140+
2141+
void Remangler::mangleCanonicalSpecializedGenericTypeMetadataAccessFunction(
2142+
Node *node) {
2143+
mangleSingleChildNode(node);
2144+
Buffer << "Mb";
2145+
}
2146+
21362147
/// The top-level interface to the remangler.
21372148
std::string Demangle::mangleNodeOld(NodePointer node) {
21382149
if (!node) return "";

lib/Demangling/Remangler.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2533,6 +2533,17 @@ void Remangler::mangleAccessorFunctionReference(Node *node) {
25332533
unreachable("can't remangle");
25342534
}
25352535

2536+
void Remangler::mangleCanonicalSpecializedGenericMetaclass(Node *node) {
2537+
mangleChildNodes(node);
2538+
Buffer << "MM";
2539+
}
2540+
2541+
void Remangler::mangleCanonicalSpecializedGenericTypeMetadataAccessFunction(
2542+
Node *node) {
2543+
mangleSingleChildNode(node);
2544+
Buffer << "Mb";
2545+
}
2546+
25362547
} // anonymous namespace
25372548

25382549
/// The top-level interface to the remangler.

lib/IRGen/ClassTypeInfo.h

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//===--- ClassTypeInfo.h - The layout info for class types. -----*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file contains layout information for class types.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef SWIFT_IRGEN_CLASSTYPEINFO_H
18+
#define SWIFT_IRGEN_CLASSTYPEINFO_H
19+
20+
#include "ClassLayout.h"
21+
#include "HeapTypeInfo.h"
22+
23+
namespace swift {
24+
namespace irgen {
25+
26+
/// Layout information for class types.
27+
class ClassTypeInfo : public HeapTypeInfo<ClassTypeInfo> {
28+
ClassDecl *TheClass;
29+
30+
// The resilient layout of the class, without making any assumptions
31+
// that violate resilience boundaries. This is used to allocate
32+
// and deallocate instances of the class, and to access fields.
33+
mutable Optional<ClassLayout> ResilientLayout;
34+
35+
// A completely fragile layout, used for metadata emission.
36+
mutable Optional<ClassLayout> FragileLayout;
37+
38+
/// Can we use swift reference-counting, or do we have to use
39+
/// objc_retain/release?
40+
const ReferenceCounting Refcount;
41+
42+
ClassLayout generateLayout(IRGenModule &IGM, SILType classType,
43+
bool forBackwardDeployment) const;
44+
45+
public:
46+
ClassTypeInfo(llvm::PointerType *irType, Size size, SpareBitVector spareBits,
47+
Alignment align, ClassDecl *theClass,
48+
ReferenceCounting refcount)
49+
: HeapTypeInfo(irType, size, std::move(spareBits), align),
50+
TheClass(theClass), Refcount(refcount) {}
51+
52+
ReferenceCounting getReferenceCounting() const { return Refcount; }
53+
54+
ClassDecl *getClass() const { return TheClass; }
55+
56+
const ClassLayout &getClassLayout(IRGenModule &IGM, SILType type,
57+
bool forBackwardDeployment) const;
58+
59+
StructLayout *createLayoutWithTailElems(IRGenModule &IGM, SILType classType,
60+
ArrayRef<SILType> tailTypes) const;
61+
};
62+
63+
} // namespace irgen
64+
} // namespace swift
65+
66+
#endif

0 commit comments

Comments
 (0)