Skip to content

Commit 7abb9e8

Browse files
authored
Merge pull request #77151 from swiftlang/revert-77038-stop-spare-bits-debug
Revert "[DebugInfo] Stop emitting spare bits mask in debug info"
2 parents 0de4a3a + 2523660 commit 7abb9e8

File tree

13 files changed

+366
-9
lines changed

13 files changed

+366
-9
lines changed

include/swift/RemoteInspection/DescriptorFinder.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,26 @@ struct FieldDescriptorBase {
9393
getFieldRecords() = 0;
9494
};
9595

96+
struct MultiPayloadEnumDescriptorBase {
97+
virtual ~MultiPayloadEnumDescriptorBase(){};
98+
99+
virtual llvm::StringRef getMangledTypeName() = 0;
100+
101+
virtual uint32_t getContentsSizeInWords() const = 0;
102+
103+
virtual size_t getSizeInBytes() const = 0;
104+
105+
virtual uint32_t getFlags() const = 0;
106+
107+
virtual bool usesPayloadSpareBits() const = 0;
108+
109+
virtual uint32_t getPayloadSpareBitMaskByteOffset() const = 0;
110+
111+
virtual uint32_t getPayloadSpareBitMaskByteCount() const = 0;
112+
113+
virtual const uint8_t *getPayloadSpareBits() const = 0;
114+
115+
};
96116
/// Interface for finding type descriptors. Implementors may provide descriptors
97117
/// that live inside or outside reflection metadata.
98118
struct DescriptorFinder {
@@ -104,6 +124,9 @@ struct DescriptorFinder {
104124

105125
virtual std::unique_ptr<FieldDescriptorBase>
106126
getFieldDescriptor(const TypeRef *TR) = 0;
127+
128+
virtual std::unique_ptr<MultiPayloadEnumDescriptorBase>
129+
getMultiPayloadEnumDescriptor(const TypeRef *TR) { abort(); };
107130
};
108131

109132
} // namespace reflection

include/swift/RemoteInspection/Records.h

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,111 @@ class BuiltinTypeDescriptor {
378378
}
379379
};
380380

381+
class MultiPayloadEnumDescriptor {
382+
public:
383+
const RelativeDirectPointer<const char> TypeName;
384+
385+
private:
386+
// This descriptor contains a series of 32-bit words
387+
uint32_t contents[];
388+
389+
// Properties are stored in `contents` at particular indexes:
390+
391+
// uint32_t SizeFlags;
392+
// Upper 16 bits are the size of the contents (in 32-bit words):
393+
// (This allows us to expand this structure in the future;
394+
// new fields should have accessors that test whether the
395+
// size is large enough and return "non-existent" if the
396+
// descriptor isn't large enough to have that field.)
397+
// Lower 16 bits are flag bits
398+
399+
int getSizeFlagsIndex() const { return 0; }
400+
401+
// uint32_t PayloadSpareBitMaskByteOffsetCount;
402+
// Number of bytes in "payload spare bits", and
403+
// offset of them within the payload area
404+
// Only present if `usePayloadSpareBits()`
405+
406+
int getPayloadSpareBitMaskByteCountIndex() const {
407+
return getSizeFlagsIndex() + 1;
408+
}
409+
410+
// uint8_t *PayloadSpareBits;
411+
// Variably-sized bitmask field (padded to a multiple of 4 bytes)
412+
// Only present if `usePayloadSpareBits()`
413+
414+
int getPayloadSpareBitsIndex() const {
415+
int PayloadSpareBitMaskByteCountFieldSize = usesPayloadSpareBits() ? 1 : 0;
416+
return getPayloadSpareBitMaskByteCountIndex() + PayloadSpareBitMaskByteCountFieldSize;
417+
}
418+
419+
// uint32_t foo;
420+
// TODO: Some future field
421+
// int getFooIndex() const {
422+
// int PayloadSpareBitMaskFieldSize = (getPayloadSpareBitMaskByteCount() + 3) / 4;
423+
// return getPayloadSpareBitsIndex() + PayloadSpareBitMaskFieldSize;
424+
// }
425+
426+
// uint32_t getFoo() const {
427+
// if (getFooIndex() < getContentsSizeInWords()) {
428+
// return contents[getFooIndex()];
429+
// } else {
430+
// return 0; // Field isn't present
431+
// }
432+
// }
433+
434+
public:
435+
//
436+
// Data derived from the above...
437+
//
438+
439+
uint32_t getContentsSizeInWords() const {
440+
return contents[getSizeFlagsIndex()] >> 16;
441+
}
442+
443+
size_t getSizeInBytes() const {
444+
// assert(getContentsSizeInWords() > 0 && "Malformed MPEnum reflection record");
445+
size_t sizeInBytes = sizeof(TypeName) + getContentsSizeInWords() * 4;
446+
return sizeInBytes;
447+
}
448+
449+
uint32_t getFlags() const {
450+
assert(getContentsSizeInWords() > 0 && "Malformed MPEnum reflection record");
451+
return contents[getSizeFlagsIndex()] & 0xffff;
452+
}
453+
454+
bool usesPayloadSpareBits() const {
455+
return getFlags() & 1;
456+
}
457+
458+
uint32_t getPayloadSpareBitMaskByteOffset() const {
459+
if (usesPayloadSpareBits()) {
460+
return contents[getPayloadSpareBitMaskByteCountIndex()] >> 16;
461+
} else {
462+
return 0;
463+
}
464+
}
465+
466+
uint32_t getPayloadSpareBitMaskByteCount() const {
467+
if (usesPayloadSpareBits()) {
468+
auto byteCount = contents[getPayloadSpareBitMaskByteCountIndex()] & 0xffff;
469+
assert(getContentsSizeInWords() >= 2 + (byteCount + 3) / 4
470+
&& "Malformed MPEnum reflection record: mask bigger than record");
471+
return byteCount;
472+
} else {
473+
return 0;
474+
}
475+
}
476+
477+
const uint8_t *getPayloadSpareBits() const {
478+
if (usesPayloadSpareBits()) {
479+
return reinterpret_cast<const uint8_t *>(&contents[getPayloadSpareBitsIndex()]);
480+
} else {
481+
return nullptr;
482+
}
483+
}
484+
};
485+
381486
class CaptureTypeRecord {
382487
public:
383488
const RelativeDirectPointer<const char> MangledTypeName;

include/swift/RemoteInspection/ReflectionContext.h

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -335,14 +335,17 @@ class ReflectionContext
335335
ObjectFileFormat.getSectionName(ReflectionSectionKind::reflstr));
336336
auto ConformMdSec = findMachOSectionByName(
337337
ObjectFileFormat.getSectionName(ReflectionSectionKind::conform));
338+
auto MPEnumMdSec = findMachOSectionByName(
339+
ObjectFileFormat.getSectionName(ReflectionSectionKind::mpenum));
338340

339341
if (FieldMdSec.first == nullptr &&
340342
AssocTySec.first == nullptr &&
341343
BuiltinTySec.first == nullptr &&
342344
CaptureSec.first == nullptr &&
343345
TypeRefMdSec.first == nullptr &&
344346
ReflStrMdSec.first == nullptr &&
345-
ConformMdSec.first == nullptr)
347+
ConformMdSec.first == nullptr &&
348+
MPEnumMdSec.first == nullptr)
346349
return {};
347350

348351
ReflectionInfo info = {{FieldMdSec.first, FieldMdSec.second},
@@ -352,6 +355,7 @@ class ReflectionContext
352355
{TypeRefMdSec.first, TypeRefMdSec.second},
353356
{ReflStrMdSec.first, ReflStrMdSec.second},
354357
{ConformMdSec.first, ConformMdSec.second},
358+
{MPEnumMdSec.first, MPEnumMdSec.second},
355359
PotentialModuleNames};
356360

357361
auto InfoID = this->addReflectionInfo(info);
@@ -466,14 +470,17 @@ class ReflectionContext
466470
ObjectFileFormat.getSectionName(ReflectionSectionKind::reflstr));
467471
auto ConformMdSec = findCOFFSectionByName(
468472
ObjectFileFormat.getSectionName(ReflectionSectionKind::conform));
473+
auto MPEnumMdSec = findCOFFSectionByName(
474+
ObjectFileFormat.getSectionName(ReflectionSectionKind::mpenum));
469475

470476
if (FieldMdSec.first == nullptr &&
471477
AssocTySec.first == nullptr &&
472478
BuiltinTySec.first == nullptr &&
473479
CaptureSec.first == nullptr &&
474480
TypeRefMdSec.first == nullptr &&
475481
ReflStrMdSec.first == nullptr &&
476-
ConformMdSec.first == nullptr)
482+
ConformMdSec.first == nullptr &&
483+
MPEnumMdSec.first == nullptr)
477484
return {};
478485

479486
ReflectionInfo Info = {{FieldMdSec.first, FieldMdSec.second},
@@ -483,6 +490,7 @@ class ReflectionContext
483490
{TypeRefMdSec.first, TypeRefMdSec.second},
484491
{ReflStrMdSec.first, ReflStrMdSec.second},
485492
{ConformMdSec.first, ConformMdSec.second},
493+
{MPEnumMdSec.first, MPEnumMdSec.second},
486494
PotentialModuleNames};
487495
return this->addReflectionInfo(Info);
488496
}
@@ -679,6 +687,9 @@ class ReflectionContext
679687
ObjectFileFormat.getSectionName(ReflectionSectionKind::reflstr), true);
680688
auto ConformMdSec = findELFSectionByName(
681689
ObjectFileFormat.getSectionName(ReflectionSectionKind::conform), true);
690+
auto MPEnumMdSec = findELFSectionByName(
691+
ObjectFileFormat.getSectionName(ReflectionSectionKind::mpenum), true);
692+
682693
if (Error)
683694
return {};
684695

@@ -688,14 +699,15 @@ class ReflectionContext
688699
// ELF executable.
689700
if (FieldMdSec.first || AssocTySec.first || BuiltinTySec.first ||
690701
CaptureSec.first || TypeRefMdSec.first || ReflStrMdSec.first ||
691-
ConformMdSec.first) {
702+
ConformMdSec.first || MPEnumMdSec.first) {
692703
ReflectionInfo info = {{FieldMdSec.first, FieldMdSec.second},
693704
{AssocTySec.first, AssocTySec.second},
694705
{BuiltinTySec.first, BuiltinTySec.second},
695706
{CaptureSec.first, CaptureSec.second},
696707
{TypeRefMdSec.first, TypeRefMdSec.second},
697708
{ReflStrMdSec.first, ReflStrMdSec.second},
698709
{ConformMdSec.first, ConformMdSec.second},
710+
{MPEnumMdSec.first, MPEnumMdSec.second},
699711
PotentialModuleNames};
700712
result = this->addReflectionInfo(info);
701713
}
@@ -718,20 +730,23 @@ class ReflectionContext
718730
ObjectFileFormat.getSectionName(ReflectionSectionKind::reflstr), false);
719731
ConformMdSec = findELFSectionByName(
720732
ObjectFileFormat.getSectionName(ReflectionSectionKind::conform), false);
733+
MPEnumMdSec = findELFSectionByName(
734+
ObjectFileFormat.getSectionName(ReflectionSectionKind::mpenum), false);
721735

722736
if (Error)
723737
return {};
724738

725739
if (FieldMdSec.first || AssocTySec.first || BuiltinTySec.first ||
726740
CaptureSec.first || TypeRefMdSec.first || ReflStrMdSec.first ||
727-
ConformMdSec.first) {
741+
ConformMdSec.first || MPEnumMdSec.first) {
728742
ReflectionInfo info = {{FieldMdSec.first, FieldMdSec.second},
729743
{AssocTySec.first, AssocTySec.second},
730744
{BuiltinTySec.first, BuiltinTySec.second},
731745
{CaptureSec.first, CaptureSec.second},
732746
{TypeRefMdSec.first, TypeRefMdSec.second},
733747
{ReflStrMdSec.first, ReflStrMdSec.second},
734748
{ConformMdSec.first, ConformMdSec.second},
749+
{MPEnumMdSec.first, MPEnumMdSec.second},
735750
PotentialModuleNames};
736751
auto rid = this->addReflectionInfo(info);
737752
if (!result)
@@ -846,8 +861,7 @@ class ReflectionContext
846861
ReflectionSectionKind::fieldmd, ReflectionSectionKind::assocty,
847862
ReflectionSectionKind::builtin, ReflectionSectionKind::capture,
848863
ReflectionSectionKind::typeref, ReflectionSectionKind::reflstr,
849-
ReflectionSectionKind::conform
850-
};
864+
ReflectionSectionKind::conform, ReflectionSectionKind::mpenum};
851865

852866
llvm::SmallVector<std::pair<RemoteRef<void>, uint64_t>, 6> Pairs;
853867
for (auto Section : Sections) {
@@ -873,6 +887,7 @@ class ReflectionContext
873887
{Pairs[4].first, Pairs[4].second},
874888
{Pairs[5].first, Pairs[5].second},
875889
{Pairs[6].first, Pairs[6].second},
890+
{Pairs[7].first, Pairs[7].second},
876891
PotentialModuleNames};
877892
return addReflectionInfo(Info);
878893
}

include/swift/RemoteInspection/RuntimeHeaders/llvm/BinaryFormat/Swift.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,4 @@ HANDLE_SWIFT_SECTION(protocs, "__swift5_protos", "swift5_protocols",
3030
".sw5prt$B")
3131
HANDLE_SWIFT_SECTION(acfuncs, "__swift5_acfuncs", "swift5_accessible_functions",
3232
".sw5acfn$B")
33+
HANDLE_SWIFT_SECTION(mpenum, "__swift5_mpenum", "swift5_mpenum", ".sw5mpen$B")

include/swift/RemoteInspection/TypeRefBuilder.h

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,21 @@ class CaptureDescriptorIterator
231231
};
232232
using CaptureSection = ReflectionSection<CaptureDescriptorIterator>;
233233

234+
class MultiPayloadEnumDescriptorIterator
235+
: public ReflectionSectionIteratorBase<MultiPayloadEnumDescriptorIterator,
236+
MultiPayloadEnumDescriptor> {
237+
public:
238+
MultiPayloadEnumDescriptorIterator(RemoteRef<void> Cur, uint64_t Size)
239+
: ReflectionSectionIteratorBase(Cur, Size, "MultiPayloadEnum") {}
240+
241+
static uint64_t
242+
getCurrentRecordSize(RemoteRef<MultiPayloadEnumDescriptor> MPER) {
243+
return MPER->getSizeInBytes();
244+
}
245+
};
246+
using MultiPayloadEnumSection =
247+
ReflectionSection<MultiPayloadEnumDescriptorIterator>;
248+
234249
using GenericSection = ReflectionSection<const void *>;
235250

236251
struct ReflectionInfo {
@@ -241,6 +256,7 @@ struct ReflectionInfo {
241256
GenericSection TypeReference;
242257
GenericSection ReflectionString;
243258
GenericSection Conformance;
259+
MultiPayloadEnumSection MultiPayloadEnum;
244260
llvm::SmallVector<llvm::StringRef, 1> PotentialModuleNames;
245261
};
246262

@@ -474,6 +490,10 @@ class TypeRefBuilder {
474490
/// Get the unsubstituted capture types for a closure context.
475491
ClosureContextInfo getClosureContextInfo(RemoteRef<CaptureDescriptor> CD);
476492

493+
/// Get the multipayload enum projection information for a given TR
494+
std::unique_ptr<MultiPayloadEnumDescriptorBase>
495+
getMultiPayloadEnumDescriptor(const TypeRef *TR) override;
496+
477497
const TypeRef *lookupTypeWitness(const std::string &MangledTypeName,
478498
const std::string &Member,
479499
StringRef Protocol);
@@ -496,6 +516,8 @@ class TypeRefBuilder {
496516
/// Load unsubstituted field types for a nominal type.
497517
RemoteRef<FieldDescriptor> getFieldTypeInfo(const TypeRef *TR);
498518

519+
RemoteRef<MultiPayloadEnumDescriptor> getMultiPayloadEnumInfo(const TypeRef *TR);
520+
499521
void populateFieldTypeInfoCacheWithReflectionAtIndex(size_t Index);
500522

501523
std::optional<RemoteRef<FieldDescriptor>>
@@ -557,7 +579,8 @@ class TypeRefBuilder {
557579

558580
public:
559581
///
560-
/// Dumping typerefs, field declarations, builtin types, captures
582+
/// Dumping typerefs, field declarations, builtin types, captures,
583+
/// multi-payload enums
561584
///
562585
void dumpTypeRef(RemoteRef<char> MangledName, std::ostream &stream,
563586
bool printTypeName = false);
@@ -566,6 +589,7 @@ class TypeRefBuilder {
566589
void dumpFieldSection(std::ostream &stream);
567590
void dumpBuiltinTypeSection(std::ostream &stream);
568591
void dumpCaptureSection(std::ostream &stream);
592+
void dumpMultiPayloadEnumSection(std::ostream &stream);
569593

570594
template <template <typename Runtime> class ObjCInteropKind,
571595
unsigned PointerSize>
@@ -807,6 +831,10 @@ class TypeRefBuilder {
807831
stream << "=============\n";
808832
dumpConformanceSection<ObjCInteropKind, PointerSize>(stream);
809833
stream << "\n";
834+
stream << "MULTI-PAYLOAD ENUM DESCRIPTORS:\n";
835+
stream << "===============================\n";
836+
dumpMultiPayloadEnumSection(stream);
837+
stream << "\n";
810838
}
811839
};
812840
friend struct ReflectionTypeDescriptorFinder;
@@ -1573,10 +1601,17 @@ class TypeRefBuilder {
15731601
return RDF.getClosureContextInfo(CD);
15741602
}
15751603

1604+
/// Get the multipayload enum projection information for a given TR
1605+
std::unique_ptr<MultiPayloadEnumDescriptorBase>
1606+
getMultiPayloadEnumDescriptor(const TypeRef *TR);
1607+
15761608
private:
15771609
/// Get the primitive type lowering for a builtin type.
15781610
RemoteRef<BuiltinTypeDescriptor> getBuiltinTypeInfo(const TypeRef *TR);
15791611

1612+
RemoteRef<MultiPayloadEnumDescriptor>
1613+
getMultiPayloadEnumInfo(const TypeRef *TR);
1614+
15801615
std::optional<uint64_t> multiPayloadEnumPointerMask;
15811616

15821617
public:
@@ -1606,7 +1641,6 @@ class TypeRefBuilder {
16061641
}
16071642
return multiPayloadEnumPointerMask.value();
16081643
}
1609-
16101644
FieldTypeCollectionResult
16111645
collectFieldTypes(std::optional<std::string> forMangledTypeName) {
16121646
return RDF.collectFieldTypes(forMangledTypeName);

0 commit comments

Comments
 (0)