@@ -328,8 +328,7 @@ BitMask BuiltinTypeInfo::getSpareBits(TypeConverter &TC, bool &hasAddrOnly) cons
328328 mask.keepOnlyMostSignificantBits (getSize () * 8 - intSize);
329329 return mask;
330330 } else if (
331- Name == " ypXp" || // Any.Type
332- Name == " yyXf" // 'yyXf' = @thin () -> Void function
331+ Name == " ypXp" // Any.Type
333332 ) {
334333 // Builtin types that expose pointer spare bits
335334 auto mpePointerSpareBits = TC.getBuilder ().getMultiPayloadEnumPointerMask ();
@@ -413,28 +412,42 @@ bool RecordTypeInfo::readExtraInhabitantIndex(remote::MemoryReader &reader,
413412}
414413
415414BitMask RecordTypeInfo::getSpareBits (TypeConverter &TC, bool &hasAddrOnly) const {
415+ // Start with all spare bits; we'll mask them out as we go...
416416 auto mask = BitMask::oneMask (getSize ());
417417 switch (SubKind) {
418418 case RecordKind::Invalid:
419- return mask; // FIXME: Should invalid have all spare bits? Or none? Does it matter?
419+ // FIXME: Should invalid have all spare bits? Or none? Does it matter?
420+ return mask;
420421 case RecordKind::Tuple:
421422 case RecordKind::Struct:
423+ // Regular aggregates inherit spare bits from their fields
422424 break ;
423425 case RecordKind::ThickFunction:
424- break ;
426+ // Thick functions have two fields:
427+ // * Code pointer that might be signed and/or misaligned
428+ // * Context that could be a tagged pointer
429+ mask.makeZero (); // No spare bits
430+ return mask;
425431 case RecordKind::OpaqueExistential: {
426432 // Existential storage isn't recorded as a field,
427433 // so we handle it specially here...
428434 int pointerSize = TC.targetPointerSize ();
429435 BitMask submask = BitMask::zeroMask (pointerSize * 3 );
430436 mask.andMask (submask, 0 );
431437 hasAddrOnly = true ;
438+ // Mask the rest of the fields as usual...
432439 break ;
433440 }
434441 case RecordKind::ClassExistential:
435- break ;
436- case RecordKind::ExistentialMetatype:
437- break ; // Field 0 is metadata pointer, a Builtin of type 'yyXf'
442+ // Class existential is a data pointer that does expose spare bits
443+ // ... so we can fall through ...
444+ case RecordKind::ExistentialMetatype: {
445+ // Initial metadata pointer has spare bits
446+ auto mpePointerSpareBits = TC.getBuilder ().getMultiPayloadEnumPointerMask ();
447+ mask.andMask (mpePointerSpareBits, 0 );
448+ mask.keepOnlyLeastSignificantBytes (8 );
449+ return mask;
450+ }
438451 case RecordKind::ErrorExistential:
439452 break ;
440453 case RecordKind::ClassInstance:
@@ -1071,7 +1084,20 @@ class MultiPayloadEnumTypeInfo: public EnumTypeInfo {
10711084 BitMask getMultiPayloadTagBitsMask () const {
10721085 auto payloadTagValues = NumEffectivePayloadCases - 1 ;
10731086 if (getNumCases () > NumEffectivePayloadCases) {
1074- payloadTagValues += 1 ;
1087+ // How many payload bits are there?
1088+ auto payloadBits = spareBitsMask;
1089+ payloadBits.complement (); // Non-spare bits are payload bits
1090+ auto numPayloadBits = payloadBits.countSetBits ();
1091+
1092+ if (numPayloadBits >= 32 ) {
1093+ // Lots of payload bits!! We only need one extra tag value
1094+ payloadTagValues += 1 ;
1095+ } else {
1096+ // We may need multiple tag values to cover all the non-payload cases
1097+ auto numNonPayloadCasesPerTag = 1ULL << numPayloadBits;
1098+ auto numNonPayloadCases = getNumCases () - NumEffectivePayloadCases;
1099+ payloadTagValues += (numNonPayloadCases + numNonPayloadCasesPerTag - 1 ) / numNonPayloadCasesPerTag;
1100+ }
10751101 }
10761102 int payloadTagBits = 0 ;
10771103 while (payloadTagValues > 0 ) {
0 commit comments