Skip to content

[RemoteMirror] Get spare bit info from reflection records #40906

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 42 commits into from
Feb 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
1e34a91
Initialize FieldInfo
tbkka Dec 8, 2021
2afe9b5
Expanded tests for MPEs
tbkka Dec 8, 2021
5c583eb
Restore fallback calculation of MPE spare bit mask
tbkka Dec 8, 2021
b07c084
Add MPE flag bits to the BuiltinTypeDescriptor
tbkka Dec 8, 2021
3039ec8
Store MPE layout in a new MultiPayloadEnumDescriptor reflection record
tbkka Dec 23, 2021
230387e
Typo
tbkka Jan 27, 2022
caa6787
Use memset
tbkka Jan 27, 2022
67220d0
Make `andMask` consistent with usage
tbkka Jan 27, 2022
63d1f47
Do not break old, deprecated API
tbkka Jan 27, 2022
77b5b1e
Some debugging utilities
tbkka Jan 28, 2022
6e25fd8
Use a helper to produce the right type info
tbkka Jan 28, 2022
e76c049
Be a little smarter about choosing a spare bit mask for pointers
tbkka Jan 28, 2022
70c08a0
Get the correct spare bit info from the type system
tbkka Jan 28, 2022
8b30c35
Use the correct spare bits mask; allow MPE record to grow in the future
tbkka Feb 1, 2022
05d2110
Minor code simplification
tbkka Feb 2, 2022
d3b75ad
Assert in the runtime that MPE reflection records are sane
tbkka Feb 2, 2022
0856692
Do not break legacy API
tbkka Feb 2, 2022
8f1ec22
Update comment; remove unnecessary code
tbkka Feb 2, 2022
3553665
Simply dump routine
tbkka Feb 2, 2022
1a4a9e4
Reduce the size of the reflection record
tbkka Feb 2, 2022
c41247e
Consolidate the two copies of getFormalTypeInContext()
tbkka Feb 2, 2022
9d368ce
Expand the failure messages here to help track down a bug
tbkka Feb 3, 2022
d467401
Missing include
tbkka Feb 3, 2022
e9fb6e5
More detail on this crash
tbkka Feb 3, 2022
21f82c8
More detail on this crash
tbkka Feb 3, 2022
5e3985d
Log the bytes and the type of data in the section
tbkka Feb 3, 2022
609fa7e
print numbers, not characters
tbkka Feb 4, 2022
27161d8
Clarify a comment
tbkka Feb 4, 2022
f256c03
Rename some variables for legibility
tbkka Feb 5, 2022
86d25f0
Try to make the index offsets easier to follow
tbkka Feb 5, 2022
3cd9146
Clean up the debug logging here a little bit
tbkka Feb 5, 2022
1603c6a
Add the new reflection section to the COFF and ELF declarations; decl…
tbkka Feb 5, 2022
b5d31d0
Expose MPE Spare bit mask as a global var in target, fetch from host
tbkka Feb 9, 2022
fe070c8
Merge branch 'main' into tbkka-remoteMirror-MPE-spareBits-v2
tbkka Feb 10, 2022
45d993d
Fix a merge conflict with the accessibility function section that's a…
tbkka Feb 10, 2022
32d3dc7
Merge branch 'main' into tbkka-remoteMirror-MPE-spareBits-v2
tbkka Feb 11, 2022
a87ed0c
Merge branch 'main' into tbkka-remoteMirror-MPE-spareBits-v2
tbkka Feb 11, 2022
01111fc
Enable debug assertions whenever !NDEBUG
tbkka Feb 16, 2022
673e3a0
Merge branch 'tbkka-remoteMirror-MPE-spareBits-v2' of github.com:tbkk…
tbkka Feb 16, 2022
72e3d54
New MPE test inspired by an LLDB test case
tbkka Feb 18, 2022
70dae3d
Disable mask computation for types containing enums
tbkka Feb 18, 2022
c470f7c
Merge remote-tracking branch 'github-apple/main' into tbkka-remoteMir…
tbkka Feb 18, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions include/swift/Reflection/Records.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,111 @@ class BuiltinTypeDescriptor {
}
};

class MultiPayloadEnumDescriptor {
public:
const RelativeDirectPointer<const char> TypeName;

private:
// This descriptor contains a series of 32-bit words
uint32_t contents[];

// Properties are stored in `contents` at particular indexes:

// uint32_t SizeFlags;
// Upper 16 bits are the size of the contents (in 32-bit words):
// (This allows us to expand this structure in the future;
// new fields should have accessors that test whether the
// size is large enough and return "non-existent" if the
// descriptor isn't large enough to have that field.)
// Lower 16 bits are flag bits

int getSizeFlagsIndex() const { return 0; }

// uint32_t PayloadSpareBitMaskByteOffsetCount;
// Number of bytes in "payload spare bits", and
// offset of them within the payload area
// Only present if `usePayloadSpareBits()`

int getPayloadSpareBitMaskByteCountIndex() const {
return getSizeFlagsIndex() + 1;
}

// uint8_t *PayloadSpareBits;
// Variably-sized bitmask field (padded to a multiple of 4 bytes)
// Only present if `usePayloadSpareBits()`

int getPayloadSpareBitsIndex() const {
int PayloadSpareBitMaskByteCountFieldSize = usesPayloadSpareBits() ? 1 : 0;
return getPayloadSpareBitMaskByteCountIndex() + PayloadSpareBitMaskByteCountFieldSize;
}

// uint32_t foo;
// TODO: Some future field
// int getFooIndex() const {
// int PayloadSpareBitMaskFieldSize = (getPayloadSpareBitMaskByteCount() + 3) / 4;
// return getPayloadSpareBitsIndex() + PayloadSpareBitMaskFieldSize;
// }

// uint32_t getFoo() const {
// if (getFooIndex() < getContentsSizeInWords()) {
// return contents[getFooIndex()];
// } else {
// return 0; // Field isn't present
// }
// }

public:
//
// Data derived from the above...
//

uint32_t getContentsSizeInWords() const {
return contents[getSizeFlagsIndex()] >> 16;
}

size_t getSizeInBytes() const {
// assert(getContentsSizeInWords() > 0 && "Malformed MPEnum reflection record");
size_t sizeInBytes = sizeof(TypeName) + getContentsSizeInWords() * 4;
return sizeInBytes;
}

uint32_t getFlags() const {
assert(getContentsSizeInWords() > 0 && "Malformed MPEnum reflection record");
return contents[getSizeFlagsIndex()] & 0xffff;
}

bool usesPayloadSpareBits() const {
return getFlags() & 1;
}

uint32_t getPayloadSpareBitMaskByteOffset() const {
if (usesPayloadSpareBits()) {
return contents[getPayloadSpareBitMaskByteCountIndex()] >> 16;
} else {
return 0;
}
}

uint32_t getPayloadSpareBitMaskByteCount() const {
if (usesPayloadSpareBits()) {
auto byteCount = contents[getPayloadSpareBitMaskByteCountIndex()] & 0xffff;
assert(getContentsSizeInWords() >= 2 + (byteCount + 3) / 4
&& "Malformed MPEnum reflection record: mask bigger than record");
return byteCount;
} else {
return 0;
}
}

const uint8_t *getPayloadSpareBits() const {
if (usesPayloadSpareBits()) {
return reinterpret_cast<const uint8_t *>(&contents[getPayloadSpareBitsIndex()]);
} else {
return nullptr;
}
}
};

class CaptureTypeRecord {
public:
const RelativeDirectPointer<const char> MangledTypeName;
Expand Down
29 changes: 20 additions & 9 deletions include/swift/Reflection/ReflectionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,14 +272,17 @@ class ReflectionContext
ObjectFileFormat.getSectionName(ReflectionSectionKind::reflstr));
auto ConformMdSec = findMachOSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::conform));
auto MPEnumMdSec = findMachOSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::mpenum));

if (FieldMdSec.first == nullptr &&
AssocTySec.first == nullptr &&
BuiltinTySec.first == nullptr &&
CaptureSec.first == nullptr &&
TypeRefMdSec.first == nullptr &&
ReflStrMdSec.first == nullptr &&
ConformMdSec.first == nullptr)
ConformMdSec.first == nullptr &&
MPEnumMdSec.first == nullptr)
return false;

ReflectionInfo info = {
Expand All @@ -289,7 +292,8 @@ class ReflectionContext
{CaptureSec.first, CaptureSec.second},
{TypeRefMdSec.first, TypeRefMdSec.second},
{ReflStrMdSec.first, ReflStrMdSec.second},
{ConformMdSec.first, ConformMdSec.second}};
{ConformMdSec.first, ConformMdSec.second},
{MPEnumMdSec.first, MPEnumMdSec.second}};

this->addReflectionInfo(info);

Expand Down Expand Up @@ -394,14 +398,17 @@ class ReflectionContext
ObjectFileFormat.getSectionName(ReflectionSectionKind::reflstr));
auto ConformMdSec = findCOFFSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::conform));
auto MPEnumMdSec = findCOFFSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::mpenum));

if (FieldMdSec.first == nullptr &&
AssocTySec.first == nullptr &&
BuiltinTySec.first == nullptr &&
CaptureSec.first == nullptr &&
TypeRefMdSec.first == nullptr &&
ReflStrMdSec.first == nullptr &&
ConformMdSec.first == nullptr)
ConformMdSec.first == nullptr &&
MPEnumMdSec.first == nullptr)
return false;

ReflectionInfo Info = {
Expand All @@ -411,7 +418,8 @@ class ReflectionContext
{CaptureSec.first, CaptureSec.second},
{TypeRefMdSec.first, TypeRefMdSec.second},
{ReflStrMdSec.first, ReflStrMdSec.second},
{ConformMdSec.first, ConformMdSec.second}};
{ConformMdSec.first, ConformMdSec.second},
{MPEnumMdSec.first, MPEnumMdSec.second}};
this->addReflectionInfo(Info);
return true;
}
Expand Down Expand Up @@ -577,6 +585,8 @@ class ReflectionContext
ObjectFileFormat.getSectionName(ReflectionSectionKind::reflstr));
auto ConformMdSec = findELFSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::conform));
auto MPEnumMdSec = findELFSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::mpenum));

if (Error)
return false;
Expand All @@ -589,7 +599,8 @@ class ReflectionContext
CaptureSec.first == nullptr &&
TypeRefMdSec.first == nullptr &&
ReflStrMdSec.first == nullptr &&
ConformMdSec.first == nullptr)
ConformMdSec.first == nullptr &&
MPEnumMdSec.first == nullptr)
return false;

ReflectionInfo info = {
Expand All @@ -599,7 +610,8 @@ class ReflectionContext
{CaptureSec.first, CaptureSec.second},
{TypeRefMdSec.first, TypeRefMdSec.second},
{ReflStrMdSec.first, ReflStrMdSec.second},
{ConformMdSec.first, ConformMdSec.second}};
{ConformMdSec.first, ConformMdSec.second},
{MPEnumMdSec.first, MPEnumMdSec.second}};

this->addReflectionInfo(info);
return true;
Expand Down Expand Up @@ -701,8 +713,7 @@ class ReflectionContext
ReflectionSectionKind::fieldmd, ReflectionSectionKind::assocty,
ReflectionSectionKind::builtin, ReflectionSectionKind::capture,
ReflectionSectionKind::typeref, ReflectionSectionKind::reflstr,
ReflectionSectionKind::conform
};
ReflectionSectionKind::conform, ReflectionSectionKind::mpenum};

llvm::SmallVector<std::pair<RemoteRef<void>, uint64_t>, 6> Pairs;
for (auto Section : Sections) {
Expand All @@ -725,7 +736,7 @@ class ReflectionContext
{Pairs[0].first, Pairs[0].second}, {Pairs[1].first, Pairs[1].second},
{Pairs[2].first, Pairs[2].second}, {Pairs[3].first, Pairs[3].second},
{Pairs[4].first, Pairs[4].second}, {Pairs[5].first, Pairs[5].second},
{Pairs[6].first, Pairs[6].second}};
{Pairs[6].first, Pairs[6].second}, {Pairs[7].first, Pairs[7].second}};
this->addReflectionInfo(Info);
return true;
}
Expand Down
5 changes: 5 additions & 0 deletions include/swift/Reflection/TypeLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,11 @@ class TypeConverter {
getClassInstanceTypeInfo(const TypeRef *TR, unsigned start,
remote::TypeInfoProvider *ExternalTypeInfo);

unsigned targetPointerSize() {
auto *rawPointerTI = getTypeInfo(getRawPointerTypeRef(), nullptr);
return rawPointerTI->getSize();
}

private:
friend class swift::reflection::LowerType;
friend class swift::reflection::EnumTypeInfoBuilder;
Expand Down
Loading