Skip to content

Commit 824bd75

Browse files
committed
IRGen: Emit typerefs for all builtin types referenced from reflection metadata sections
In order to perform layout, the remote mirrors library needs to know about the size, alignment and extra inhabitants of builtin types. Ideally we would emit a reflection info section in libswiftRuntime.o, but in the meantime just duplicate builtin type metadata for all builtin types referenced from the current module instead. In practice only the stdlib and a handful of overlays like the SIMD overlay use builtin types, and only a few at a time. Tested manually by running swift-reflection-tool on the standard library -- I'll add automated tests by using -parse-stdlib to reference Builtin types in a subsequent patch that adds more layout logic. NFC if -enable-reflection-metadata is off.
1 parent f236383 commit 824bd75

File tree

13 files changed

+347
-182
lines changed

13 files changed

+347
-182
lines changed

include/swift/Reflection/Records.h

Lines changed: 62 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
namespace swift {
2323
namespace reflection {
2424

25+
// Field records describe the type of a single stored property or case member
26+
// of a class, struct or enum.
2527
class FieldRecordFlags {
2628
using int_type = uint32_t;
2729
enum : int_type {
@@ -97,6 +99,8 @@ struct FieldRecordIterator {
9799
}
98100
};
99101

102+
// Field descriptors contain a collection of field records for a single
103+
// class, struct or enum declaration.
100104
struct FieldDescriptor {
101105
const FieldRecord *getFieldRecordBuffer() const {
102106
return reinterpret_cast<const FieldRecord *>(this + 1);
@@ -127,6 +131,37 @@ struct FieldDescriptor {
127131
}
128132
};
129133

134+
class FieldDescriptorIterator
135+
: public std::iterator<std::forward_iterator_tag, FieldDescriptor> {
136+
public:
137+
const void *Cur;
138+
const void * const End;
139+
FieldDescriptorIterator(const void *Cur, const void * const End)
140+
: Cur(Cur), End(End) {}
141+
142+
const FieldDescriptor &operator*() const {
143+
return *reinterpret_cast<const FieldDescriptor *>(Cur);
144+
}
145+
146+
FieldDescriptorIterator &operator++() {
147+
const auto &FR = this->operator*();
148+
const void *Next = reinterpret_cast<const char *>(Cur)
149+
+ sizeof(FieldDescriptor) + FR.NumFields * FR.FieldRecordSize;
150+
Cur = Next;
151+
return *this;
152+
}
153+
154+
bool operator==(FieldDescriptorIterator const &other) const {
155+
return Cur == other.Cur && End == other.End;
156+
}
157+
158+
bool operator!=(FieldDescriptorIterator const &other) const {
159+
return !(*this == other);
160+
}
161+
};
162+
163+
// Associated type records describe the mapping from an associated
164+
// type to the type witness of a conformance.
130165
class AssociatedTypeRecord {
131166
const RelativeDirectPointer<const char> Name;
132167
const RelativeDirectPointer<const char> SubstitutedTypeName;
@@ -179,6 +214,8 @@ struct AssociatedTypeRecordIterator {
179214
}
180215
};
181216

217+
// An associated type descriptor contains a collection of associated
218+
// type records for a conformance.
182219
struct AssociatedTypeDescriptor {
183220
const RelativeDirectPointer<const char> ConformingTypeName;
184221
const RelativeDirectPointer<const char> ProtocolTypeName;
@@ -243,36 +280,50 @@ class AssociatedTypeIterator
243280
}
244281
};
245282

246-
class FieldDescriptorIterator
247-
: public std::iterator<std::forward_iterator_tag, FieldDescriptor> {
283+
// Builtin type records describe basic layout information about
284+
// any builtin types referenced from the other sections.
285+
class BuiltinTypeDescriptor {
286+
const RelativeDirectPointer<const char> TypeName;
287+
288+
public:
289+
uint32_t Size;
290+
uint32_t Alignment;
291+
uint32_t Stride;
292+
uint32_t NumExtraInhabitants;
293+
294+
std::string getMangledTypeName() const {
295+
return TypeName.get();
296+
}
297+
};
298+
299+
class BuiltinTypeDescriptorIterator
300+
: public std::iterator<std::forward_iterator_tag, BuiltinTypeDescriptor> {
248301
public:
249302
const void *Cur;
250303
const void * const End;
251-
FieldDescriptorIterator(const void *Cur, const void * const End)
304+
BuiltinTypeDescriptorIterator(const void *Cur, const void * const End)
252305
: Cur(Cur), End(End) {}
253306

254-
const FieldDescriptor &operator*() const {
255-
return *reinterpret_cast<const FieldDescriptor *>(Cur);
307+
const BuiltinTypeDescriptor &operator*() const {
308+
return *reinterpret_cast<const BuiltinTypeDescriptor *>(Cur);
256309
}
257310

258-
FieldDescriptorIterator &operator++() {
259-
const auto &FR = this->operator*();
311+
BuiltinTypeDescriptorIterator &operator++() {
260312
const void *Next = reinterpret_cast<const char *>(Cur)
261-
+ sizeof(FieldDescriptor) + FR.NumFields * FR.FieldRecordSize;
313+
+ sizeof(BuiltinTypeDescriptor);
262314
Cur = Next;
263315
return *this;
264316
}
265317

266-
bool operator==(FieldDescriptorIterator const &other) const {
318+
bool operator==(BuiltinTypeDescriptorIterator const &other) const {
267319
return Cur == other.Cur && End == other.End;
268320
}
269321

270-
bool operator!=(FieldDescriptorIterator const &other) const {
322+
bool operator!=(BuiltinTypeDescriptorIterator const &other) const {
271323
return !(*this == other);
272324
}
273325
};
274326

275-
276327
} // end namespace reflection
277328
} // end namespace swift
278329

include/swift/Reflection/ReflectionContext.h

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,17 @@ using swift::remote::RemoteAddress;
3939
template <typename Iterator>
4040
class ReflectionSection {
4141
using const_iterator = Iterator;
42-
const void * const Begin;
43-
const void * const End;
42+
const void * Begin;
43+
const void * End;
4444

4545
public:
46-
ReflectionSection(const void * const Begin,
47-
const void * const End)
46+
ReflectionSection(const void * Begin,
47+
const void * End)
4848
: Begin(Begin), End(End) {}
4949

5050
ReflectionSection(uint64_t Begin, uint64_t End)
51-
: Begin(reinterpret_cast<const void * const>(Begin)),
52-
End(reinterpret_cast<const void * const>(End)) {}
51+
: Begin(reinterpret_cast<const void *>(Begin)),
52+
End(reinterpret_cast<const void *>(End)) {}
5353

5454
void *startAddress() {
5555
return const_cast<void *>(Begin);
@@ -177,14 +177,16 @@ class TypeRefBuilder {
177177

178178
using FieldSection = ReflectionSection<FieldDescriptorIterator>;
179179
using AssociatedTypeSection = ReflectionSection<AssociatedTypeIterator>;
180+
using BuiltinTypeSection = ReflectionSection<BuiltinTypeDescriptorIterator>;
180181
using GenericSection = ReflectionSection<const void *>;
181182

182183
struct ReflectionInfo {
183184
std::string ImageName;
184185
FieldSection fieldmd;
185186
AssociatedTypeSection assocty;
186-
GenericSection reflstr;
187+
BuiltinTypeSection builtin;
187188
GenericSection typeref;
189+
GenericSection reflstr;
188190
};
189191

190192

@@ -295,16 +297,34 @@ class ReflectionContext
295297
}
296298
}
297299

300+
void dumpBuiltinTypeSection(std::ostream &OS) {
301+
for (const auto &sections : ReflectionInfos) {
302+
for (const auto &descriptor : sections.builtin) {
303+
auto typeName = Demangle::demangleTypeAsString(
304+
descriptor.getMangledTypeName());
305+
306+
OS << typeName << " :\n";
307+
OS << "Size: " << descriptor.Size << "\n";
308+
OS << "Alignment: " << descriptor.Alignment << "\n";
309+
OS << "Stride: " << descriptor.Stride << "\n";
310+
OS << "NumExtraInhabitants: " << descriptor.NumExtraInhabitants << "\n";
311+
}
312+
}
313+
}
314+
298315
void dumpAllSections(std::ostream &OS) {
299316
OS << "FIELDS:\n";
300-
for (size_t i = 0; i < 7; ++i) OS << '=';
301-
OS << '\n';
317+
OS << "=======\n";
302318
dumpFieldSection(OS);
303-
OS << "\nASSOCIATED TYPES:\n";
304-
for (size_t i = 0; i < 17; ++i) OS << '=';
305319
OS << '\n';
320+
OS << "ASSOCIATED TYPES:\n";
321+
OS << "=================\n";
306322
dumpAssociatedTypeSection(OS);
307323
OS << '\n';
324+
OS << "BUILTIN TYPES:\n";
325+
OS << "==============\n";
326+
dumpBuiltinTypeSection(OS);
327+
OS << '\n';
308328
}
309329

310330
TypeRef *

include/swift/SwiftRemoteMirror/SwiftRemoteMirror.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,10 @@ void
5151
swift_reflection_addReflectionInfo(SwiftReflectionContextRef ContextRef,
5252
const char *ImageName,
5353
swift_reflection_section_t fieldmd,
54+
swift_reflection_section_t builtin,
55+
swift_reflection_section_t assocty,
5456
swift_reflection_section_t typeref,
55-
swift_reflection_section_t reflstr,
56-
swift_reflection_section_t assocty);
57+
swift_reflection_section_t reflstr);
5758

5859

5960
/// Returns an opaque type reference for a metadata pointer, or

lib/IRGen/GenDecl.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -879,15 +879,9 @@ void IRGenModuleDispatcher::emitTypeMetadataRecords() {
879879
}
880880
}
881881

882-
void IRGenModuleDispatcher::emitFieldTypeMetadataRecords() {
882+
void IRGenModuleDispatcher::emitReflectionMetadataRecords() {
883883
for (auto &m : *this) {
884-
m.second->emitFieldTypeMetadataRecords();
885-
}
886-
}
887-
888-
void IRGenModuleDispatcher::emitAssociatedTypeMetadataRecords() {
889-
for (auto &m : *this) {
890-
m.second->emitAssociatedTypeMetadataRecords();
884+
m.second->emitReflectionMetadataRecords();
891885
}
892886
}
893887

0 commit comments

Comments
 (0)