Skip to content

Commit 6240fe3

Browse files
committed
IRGen: Calculate if a class needs a metadata pattern as part of layout
This will be used for layout of classes containing resiliently-sized fields.
1 parent 5098ca9 commit 6240fe3

File tree

3 files changed

+26
-2
lines changed

3 files changed

+26
-2
lines changed

lib/IRGen/GenClass.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,11 @@ namespace {
168168

169169
unsigned NumInherited = 0;
170170

171+
// Does the class require a metadata template? This will be true if
172+
// the class or any of its ancestors have generic parameters, or if
173+
// any of the below conditions are false.
174+
bool ClassHasMetadataPattern = false;
175+
171176
// Does the superclass have a fixed number of stored properties?
172177
// If not, and the class has generally-dependent layout, we have to
173178
// access stored properties through an indirect offset into the field
@@ -212,6 +217,7 @@ namespace {
212217
fieldLayout.InheritedStoredProperties = inheritedStoredProps;
213218
fieldLayout.AllFieldAccesses = IGM.Context.AllocateCopy(AllFieldAccesses);
214219
fieldLayout.MetadataAccess = MetadataAccess;
220+
fieldLayout.HasMetadataPattern = ClassHasMetadataPattern;
215221
return fieldLayout;
216222
}
217223

@@ -237,6 +243,8 @@ namespace {
237243
} else if (IGM.isResilient(superclass, ResilienceScope::Component)) {
238244
// If the superclass is resilient, the number of stored properties
239245
// is not known at compile time.
246+
ClassHasMetadataPattern = true;
247+
240248
ClassHasFixedFieldCount = false;
241249
ClassHasFixedSize = false;
242250

@@ -246,6 +254,9 @@ namespace {
246254
if (superclass->isGenericContext())
247255
ClassHasConcreteLayout = false;
248256
} else {
257+
if (superclass->isGenericContext())
258+
ClassHasMetadataPattern = true;
259+
249260
// Otherwise, we have total knowledge of the class and its
250261
// fields, so walk them to compute the layout.
251262
addFieldsForClass(superclass, superclassType);
@@ -269,10 +280,11 @@ namespace {
269280
auto &eltType = IGM.getTypeInfo(type);
270281

271282
if (!eltType.isFixedSize()) {
283+
ClassHasMetadataPattern = true;
284+
ClassHasFixedSize = false;
285+
272286
if (type.hasArchetype())
273287
ClassHasConcreteLayout = false;
274-
275-
ClassHasFixedSize = false;
276288
}
277289

278290
Elements.push_back(ElementLayout::getIncomplete(eltType));
@@ -1826,3 +1838,11 @@ ClassDecl *irgen::getRootClassForMetaclass(IRGenModule &IGM, ClassDecl *C) {
18261838

18271839
return IGM.getObjCRuntimeBaseClass(IGM.Context.Id_SwiftObject);
18281840
}
1841+
1842+
bool irgen::getClassHasMetadataPattern(IRGenModule &IGM, ClassDecl *theClass) {
1843+
// Classes imported from Objective-C never have a metadata pattern.
1844+
if (theClass->hasClangNode())
1845+
return false;
1846+
1847+
return getSelfTypeInfo(IGM, theClass).getClassLayout(IGM).HasMetadataPattern;
1848+
}

lib/IRGen/GenClass.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ namespace irgen {
118118
IsaEncoding getIsaEncodingForType(IRGenModule &IGM, CanType type);
119119

120120
ClassDecl *getRootClassForMetaclass(IRGenModule &IGM, ClassDecl *theClass);
121+
122+
bool getClassHasMetadataPattern(IRGenModule &IGM, ClassDecl *theClass);
121123
} // end namespace irgen
122124
} // end namespace swift
123125

lib/IRGen/StructLayout.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,8 @@ struct ClassLayout {
416416
/// Lazily-initialized metadata access method. See the comment in
417417
/// ClassLayoutBuilder.
418418
FieldAccess MetadataAccess;
419+
/// Does the class require a metadata pattern.
420+
bool HasMetadataPattern;
419421

420422
unsigned getFieldIndex(VarDecl *field) const {
421423
// FIXME: This is algorithmically terrible.

0 commit comments

Comments
 (0)