@@ -133,6 +133,22 @@ static SILType getSelfType(ClassDecl *base) {
133
133
return SILType::getPrimitiveObjectType (loweredTy);
134
134
}
135
135
136
+ // / If the superclass came from another module, we may have dropped
137
+ // / stored properties due to the Swift language version availability of
138
+ // / their types. In these cases we can't precisely lay out the ivars in
139
+ // / the class object at compile time so we need to do runtime layout.
140
+ static bool classHasIncompleteLayout (IRGenModule &IGM,
141
+ ClassDecl *theClass) {
142
+ if (theClass->getParentModule () == IGM.getSwiftModule ())
143
+ return false ;
144
+
145
+ for (auto field : theClass->getStoredPropertiesAndMissingMemberPlaceholders ())
146
+ if (isa<MissingMemberDecl>(field))
147
+ return true ;
148
+
149
+ return false ;
150
+ }
151
+
136
152
namespace {
137
153
class ClassLayoutBuilder : public StructLayoutBuilder {
138
154
SmallVector<ElementLayout, 8 > Elements;
@@ -229,6 +245,7 @@ namespace {
229
245
fieldLayout.AllFieldAccesses = IGM.Context .AllocateCopy (AllFieldAccesses);
230
246
fieldLayout.MetadataRequiresDynamicInitialization =
231
247
ClassMetadataRequiresDynamicInitialization;
248
+ fieldLayout.HasFixedSize = ClassHasFixedSize;
232
249
return fieldLayout;
233
250
}
234
251
@@ -237,9 +254,6 @@ namespace {
237
254
if (theClass->isGenericContext ())
238
255
ClassMetadataRequiresDynamicInitialization = true ;
239
256
240
- if (IGM.isResilient (theClass, ResilienceExpansion::Maximal))
241
- ClassMetadataRequiresDynamicInitialization = true ;
242
-
243
257
if (theClass->hasSuperclass ()) {
244
258
SILType superclassType = classType.getSuperclass ();
245
259
auto superclass = superclassType.getClassOrBoundGenericClass ();
@@ -251,6 +265,7 @@ namespace {
251
265
// the class object at compile time so we need to do runtime layout.
252
266
if (classHasIncompleteLayout (IGM, superclass)) {
253
267
ClassMetadataRequiresDynamicInitialization = true ;
268
+ ClassHasFixedSize = false ;
254
269
}
255
270
256
271
if (superclass->hasClangNode ()) {
@@ -282,9 +297,6 @@ namespace {
282
297
}
283
298
} else if (IGM.isResilient (superclass, ResilienceExpansion::Maximal)) {
284
299
ClassMetadataRequiresDynamicInitialization = true ;
285
-
286
- // If the superclass is resilient to us, we cannot statically
287
- // know the layout of either its instances or its class objects.
288
300
ClassHasFixedSize = false ;
289
301
290
302
// Furthermore, if the superclass is a generic context, we have to
@@ -310,6 +322,11 @@ namespace {
310
322
ClassHasFixedSize = false ;
311
323
}
312
324
325
+ if (IGM.isResilient (theClass, ResilienceExpansion::Maximal)) {
326
+ ClassMetadataRequiresDynamicInitialization = true ;
327
+ ClassHasFixedSize = false ;
328
+ }
329
+
313
330
// Access strategies should be set by the abstract class layout,
314
331
// not using the concrete type information we have.
315
332
const ClassLayout *abstractLayout = nullptr ;
@@ -657,7 +674,7 @@ Address irgen::emitTailProjection(IRGenFunction &IGF, llvm::Value *Base,
657
674
} else {
658
675
llvm::Value *metadata = emitHeapMetadataRefForHeapObject (IGF, Base,
659
676
ClassType);
660
- Offset = emitClassFragileInstanceSizeAndAlignMask (IGF,
677
+ Offset = emitClassResilientInstanceSizeAndAlignMask (IGF,
661
678
ClassType.getClassOrBoundGenericClass (),
662
679
metadata).first ;
663
680
}
@@ -789,17 +806,25 @@ llvm::Value *irgen::emitClassAllocation(IRGenFunction &IGF, SILType selfType,
789
806
emitClassHeapMetadataRef (IGF, classType, MetadataValueType::TypeMetadata,
790
807
MetadataState::Complete);
791
808
792
- // FIXME: Long-term, we clearly need a specialized runtime entry point.
809
+ const StructLayout &structLayout = classTI.getLayout (IGF.IGM , selfType);
810
+ const ClassLayout &classLayout = classTI.getClassLayout (IGF.IGM , selfType);
811
+
793
812
llvm::Value *size, *alignMask;
794
- std::tie (size, alignMask)
795
- = emitClassFragileInstanceSizeAndAlignMask (IGF,
796
- selfType.getClassOrBoundGenericClass (),
797
- metadata);
813
+ if (classLayout.HasFixedSize ) {
814
+ assert (structLayout.isFixedLayout ());
798
815
799
- const StructLayout &layout = classTI.getLayout (IGF.IGM , selfType);
800
- llvm::Type *destType = layout.getType ()->getPointerTo ();
816
+ size = structLayout.emitSize (IGF.IGM );
817
+ alignMask = structLayout.emitAlignMask (IGF.IGM );
818
+ } else {
819
+ std::tie (size, alignMask)
820
+ = emitClassResilientInstanceSizeAndAlignMask (IGF,
821
+ selfType.getClassOrBoundGenericClass (),
822
+ metadata);
823
+ }
824
+
825
+ llvm::Type *destType = structLayout.getType ()->getPointerTo ();
801
826
llvm::Value *val = nullptr ;
802
- if (llvm::Value *Promoted = stackPromote (IGF, layout , StackAllocSize,
827
+ if (llvm::Value *Promoted = stackPromote (IGF, structLayout , StackAllocSize,
803
828
TailArrays)) {
804
829
val = IGF.Builder .CreateBitCast (Promoted, IGF.IGM .RefCountedPtrTy );
805
830
val = IGF.emitInitStackObjectCall (metadata, val, " reference.new" );
@@ -863,7 +888,7 @@ static void getInstanceSizeAndAlignMask(IRGenFunction &IGF,
863
888
llvm::Value *metadata =
864
889
emitHeapMetadataRefForHeapObject (IGF, selfValue, selfType);
865
890
std::tie (size, alignMask)
866
- = emitClassFragileInstanceSizeAndAlignMask (IGF, selfClass, metadata);
891
+ = emitClassResilientInstanceSizeAndAlignMask (IGF, selfClass, metadata);
867
892
}
868
893
869
894
void irgen::emitClassDeallocation (IRGenFunction &IGF, SILType selfType,
@@ -2225,26 +2250,6 @@ ClassDecl *irgen::getRootClassForMetaclass(IRGenModule &IGM, ClassDecl *C) {
2225
2250
IGM.Context .Id_SwiftObject );
2226
2251
}
2227
2252
2228
- // / If the superclass came from another module, we may have dropped
2229
- // / stored properties due to the Swift language version availability of
2230
- // / their types. In these cases we can't precisely lay out the ivars in
2231
- // / the class object at compile time so we need to do runtime layout.
2232
- bool irgen::classHasIncompleteLayout (IRGenModule &IGM,
2233
- ClassDecl *theClass) {
2234
- do {
2235
- if (theClass->getParentModule () != IGM.getSwiftModule ()) {
2236
- for (auto field :
2237
- theClass->getStoredPropertiesAndMissingMemberPlaceholders ()){
2238
- if (isa<MissingMemberDecl>(field)) {
2239
- return true ;
2240
- }
2241
- }
2242
- return false ;
2243
- }
2244
- } while ((theClass = theClass->getSuperclassDecl ()));
2245
- return false ;
2246
- }
2247
-
2248
2253
bool irgen::doesClassMetadataRequireDynamicInitialization (IRGenModule &IGM,
2249
2254
ClassDecl *theClass) {
2250
2255
// Classes imported from Objective-C never requires dynamic initialization.
@@ -2284,36 +2289,6 @@ bool irgen::hasKnownSwiftMetadata(IRGenModule &IGM, ClassDecl *theClass) {
2284
2289
return theClass->hasKnownSwiftImplementation ();
2285
2290
}
2286
2291
2287
- // / Given a reference to class metadata of the given type,
2288
- // / load the fragile instance size and alignment of the class.
2289
- std::pair<llvm::Value *, llvm::Value *>
2290
- irgen::emitClassFragileInstanceSizeAndAlignMask (IRGenFunction &IGF,
2291
- ClassDecl *theClass,
2292
- llvm::Value *metadata) {
2293
- // FIXME: The below checks should capture this property already, but
2294
- // resilient class metadata layout is not fully implemented yet.
2295
- auto superClass = theClass;
2296
- do {
2297
- if (superClass->getParentModule () != IGF.IGM .getSwiftModule ()) {
2298
- return emitClassResilientInstanceSizeAndAlignMask (IGF, theClass,
2299
- metadata);
2300
- }
2301
- } while ((superClass = superClass->getSuperclassDecl ()));
2302
-
2303
- // If the class has fragile fixed layout, return the constant size and
2304
- // alignment.
2305
- if (llvm::Constant *size
2306
- = tryEmitClassConstantFragileInstanceSize (IGF.IGM , theClass)) {
2307
- llvm::Constant *alignMask
2308
- = tryEmitClassConstantFragileInstanceAlignMask (IGF.IGM , theClass);
2309
- assert (alignMask && " static size without static align" );
2310
- return {size, alignMask};
2311
- }
2312
-
2313
- // Otherwise, load it from the metadata.
2314
- return emitClassResilientInstanceSizeAndAlignMask (IGF, theClass, metadata);
2315
- }
2316
-
2317
2292
std::pair<llvm::Value *, llvm::Value *>
2318
2293
irgen::emitClassResilientInstanceSizeAndAlignMask (IRGenFunction &IGF,
2319
2294
ClassDecl *theClass,
0 commit comments