@@ -327,9 +327,7 @@ BitMask BuiltinTypeInfo::getSpareBits(TypeConverter &TC, bool &hasAddrOnly) cons
327327 auto mask = BitMask::oneMask (getSize ());
328328 mask.keepOnlyMostSignificantBits (getSize () * 8 - intSize);
329329 return mask;
330- } else if (
331- Name == " ypXp" || // Any.Type
332- Name == " yyXf" // 'yyXf' = @thin () -> Void function
330+ } else if (Name == " ypXp" // Any.Type
333331 ) {
334332 // Builtin types that expose pointer spare bits
335333 auto mpePointerSpareBits = TC.getBuilder ().getMultiPayloadEnumPointerMask ();
@@ -413,28 +411,42 @@ bool RecordTypeInfo::readExtraInhabitantIndex(remote::MemoryReader &reader,
413411}
414412
415413BitMask RecordTypeInfo::getSpareBits (TypeConverter &TC, bool &hasAddrOnly) const {
414+ // Start with all spare bits; we'll mask them out as we go...
416415 auto mask = BitMask::oneMask (getSize ());
417416 switch (SubKind) {
418417 case RecordKind::Invalid:
419- return mask; // FIXME: Should invalid have all spare bits? Or none? Does it matter?
418+ // FIXME: Should invalid have all spare bits? Or none? Does it matter?
419+ return mask;
420420 case RecordKind::Tuple:
421421 case RecordKind::Struct:
422+ // Regular aggregates inherit spare bits from their fields
422423 break ;
423424 case RecordKind::ThickFunction:
424- break ;
425+ // Thick functions have two fields:
426+ // * Code pointer that might be signed and/or misaligned
427+ // * Context that could be a tagged pointer
428+ mask.makeZero (); // No spare bits
429+ return mask;
425430 case RecordKind::OpaqueExistential: {
426431 // Existential storage isn't recorded as a field,
427432 // so we handle it specially here...
428433 int pointerSize = TC.targetPointerSize ();
429434 BitMask submask = BitMask::zeroMask (pointerSize * 3 );
430435 mask.andMask (submask, 0 );
431436 hasAddrOnly = true ;
437+ // Mask the rest of the fields as usual...
432438 break ;
433439 }
434440 case RecordKind::ClassExistential:
435- break ;
436- case RecordKind::ExistentialMetatype:
437- break ; // Field 0 is metadata pointer, a Builtin of type 'yyXf'
441+ // Class existential is a data pointer that does expose spare bits
442+ // ... so we can fall through ...
443+ case RecordKind::ExistentialMetatype: {
444+ // Initial metadata pointer has spare bits
445+ auto mpePointerSpareBits = TC.getBuilder ().getMultiPayloadEnumPointerMask ();
446+ mask.andMask (mpePointerSpareBits, 0 );
447+ mask.keepOnlyLeastSignificantBytes (TC.targetPointerSize ());
448+ return mask;
449+ }
438450 case RecordKind::ErrorExistential:
439451 break ;
440452 case RecordKind::ClassInstance:
@@ -1071,7 +1083,20 @@ class MultiPayloadEnumTypeInfo: public EnumTypeInfo {
10711083 BitMask getMultiPayloadTagBitsMask () const {
10721084 auto payloadTagValues = NumEffectivePayloadCases - 1 ;
10731085 if (getNumCases () > NumEffectivePayloadCases) {
1074- payloadTagValues += 1 ;
1086+ // How many payload bits are there?
1087+ auto payloadBits = spareBitsMask;
1088+ payloadBits.complement (); // Non-spare bits are payload bits
1089+ auto numPayloadBits = payloadBits.countSetBits ();
1090+
1091+ if (numPayloadBits >= 32 ) {
1092+ // Lots of payload bits!! We only need one extra tag value
1093+ payloadTagValues += 1 ;
1094+ } else {
1095+ // We may need multiple tag values to cover all the non-payload cases
1096+ auto numNonPayloadCasesPerTag = 1ULL << numPayloadBits;
1097+ auto numNonPayloadCases = getNumCases () - NumEffectivePayloadCases;
1098+ payloadTagValues += (numNonPayloadCases + numNonPayloadCasesPerTag - 1 ) / numNonPayloadCasesPerTag;
1099+ }
10751100 }
10761101 int payloadTagBits = 0 ;
10771102 while (payloadTagValues > 0 ) {
0 commit comments