Skip to content

Commit 1d5b9b0

Browse files
committed
Reflection: Add instance-specific layout entry point, and do some refactoring
Closure context layout will depend on the instance itself as well as the isa pointer, because instead of instantiating metadata for closures that capture generic parameters, we store the substitutions inside the context itself. For classes, this entry point just reads the isa pointer, applies the isa mask and proceeds down the metadata path. For now, the only the latter is hooked up.
1 parent 1bd536e commit 1d5b9b0

File tree

7 files changed

+111
-36
lines changed

7 files changed

+111
-36
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class ReflectionContext
4646
using super::getBuilder;
4747
using super::readIsaMask;
4848
using super::readTypeFromMetadata;
49+
using super::readMetadataFromInstance;
4950
using typename super::StoredPointer;
5051

5152
explicit ReflectionContext(std::shared_ptr<MemoryReader> reader)
@@ -68,7 +69,7 @@ class ReflectionContext
6869

6970
/// Return a description of the layout of a class instance with the given
7071
/// metadata as its isa pointer.
71-
const TypeInfo *getInstanceTypeInfo(StoredPointer MetadataAddress) {
72+
const TypeInfo *getMetadataTypeInfo(StoredPointer MetadataAddress) {
7273
// See if we cached the layout already
7374
auto found = Cache.find(MetadataAddress);
7475
if (found != Cache.end())
@@ -95,7 +96,7 @@ class ReflectionContext
9596

9697
// Perform layout
9798
if (valid)
98-
TI = TC.getInstanceTypeInfo(TR, size, align);
99+
TI = TC.getClassInstanceTypeInfo(TR, size, align);
99100
}
100101
break;
101102
}
@@ -109,6 +110,15 @@ class ReflectionContext
109110
return TI;
110111
}
111112

113+
/// Return a description of the layout of a class instance with the given
114+
/// metadata as its isa pointer.
115+
const TypeInfo *getInstanceTypeInfo(StoredPointer ObjectAddress) {
116+
auto MetadataAddress = readMetadataFromInstance(ObjectAddress);
117+
if (!MetadataAddress.first)
118+
return nullptr;
119+
return getMetadataTypeInfo(MetadataAddress.second);
120+
}
121+
112122
/// Return a description of the layout of a value with the given type.
113123
const TypeInfo *getTypeInfo(const TypeRef *TR) {
114124
return getBuilder().getTypeConverter().getTypeInfo(TR);

include/swift/Reflection/TypeLowering.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,9 @@ class TypeConverter {
179179
/// class.
180180
///
181181
/// Not cached.
182-
const TypeInfo *getInstanceTypeInfo(const TypeRef *TR,
183-
unsigned start,
184-
unsigned align);
182+
const TypeInfo *getClassInstanceTypeInfo(const TypeRef *TR,
183+
unsigned start,
184+
unsigned align);
185185

186186
/* Not really public */
187187
const ReferenceTypeInfo *

include/swift/Remote/MetadataReader.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,23 @@ class MetadataReader {
676676
}
677677
}
678678

679+
/// Read the isa pointer of a class or closure context instance and apply
680+
/// the isa mask.
681+
std::pair<bool, StoredPointer> readMetadataFromInstance(
682+
StoredPointer ObjectAddress) {
683+
auto isaMask = readIsaMask();
684+
if (!isaMask.first)
685+
return {false, 0};
686+
687+
StoredPointer MetadataAddress;
688+
if (!Reader->readBytes(RemoteAddress(ObjectAddress),
689+
(uint8_t*)&MetadataAddress,
690+
sizeof(StoredPointer)))
691+
return {false, 0};
692+
693+
return {true, MetadataAddress & isaMask.second};
694+
}
695+
679696
/// Given the address of a nominal type descriptor, attempt to resolve
680697
/// its nominal type declaration.
681698
BuiltNominalTypeDecl readNominalTypeFromDescriptor(StoredPointer address) {

include/swift/SwiftRemoteMirror/SwiftRemoteMirror.h

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ swift_typeref_t
7171
swift_reflection_typeRefForMetadata(SwiftReflectionContextRef ContextRef,
7272
uintptr_t Metadata);
7373

74+
/// Returns an opaque type reference for a class or closure context
75+
/// instance pointer, or NULL if one can't be constructed.
76+
swift_typeref_t
77+
swift_reflection_typeRefForInstance(SwiftReflectionContextRef ContextRef,
78+
uintptr_t Object);
79+
7480
/// Returns a structure describing the layout of a value of a typeref.
7581
/// For classes, this returns the reference value itself.
7682
swift_typeinfo_t
@@ -96,6 +102,19 @@ swift_reflection_childOfMetadata(SwiftReflectionContextRef ContextRef,
96102
uintptr_t Metadata,
97103
unsigned Index);
98104

105+
/// Returns a structure describing the layout of a class or closure
106+
/// context instance, from a pointer to the object itself.
107+
swift_typeinfo_t
108+
swift_reflection_infoForInstance(SwiftReflectionContextRef ContextRef,
109+
uintptr_t Object);
110+
111+
/// Returns the information about a child field of a class or closure
112+
/// context instance.
113+
swift_childinfo_t
114+
swift_reflection_childOfInstance(SwiftReflectionContextRef ContextRef,
115+
uintptr_t Object,
116+
unsigned Index);
117+
99118
/// Returns the number of generic arguments of a typeref.
100119
unsigned
101120
swift_reflection_genericArgumentCountOfTypeRef(swift_typeref_t OpaqueTypeRef);
@@ -133,13 +152,17 @@ int swift_reflection_projectExistential(SwiftReflectionContextRef ContextRef,
133152
/// Dump a brief description of the typeref as a tree to stderr.
134153
void swift_reflection_dumpTypeRef(swift_typeref_t OpaqueTypeRef);
135154

155+
/// Dump information about the layout for a typeref.
156+
void swift_reflection_dumpInfoForTypeRef(SwiftReflectionContextRef ContextRef,
157+
swift_typeref_t OpaqueTypeRef);
158+
136159
/// Dump information about the layout of a class instance from its isa pointer.
137160
void swift_reflection_dumpInfoForMetadata(SwiftReflectionContextRef ContextRef,
138161
uintptr_t Metadata);
139162

140-
/// Dump information about the layout for a typeref.
141-
void swift_reflection_dumpInfoForTypeRef(SwiftReflectionContextRef ContextRef,
142-
swift_typeref_t OpaqueTypeRef);
163+
/// Dump information about the layout of a class or closure context instance.
164+
void swift_reflection_dumpInfoForInstance(SwiftReflectionContextRef ContextRef,
165+
uintptr_t Object);
143166

144167
#ifdef __cplusplus
145168
} // extern "C"

stdlib/public/Reflection/TypeLowering.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -870,9 +870,9 @@ const TypeInfo *TypeConverter::getTypeInfo(const TypeRef *TR) {
870870
return TI;
871871
}
872872

873-
const TypeInfo *TypeConverter::getInstanceTypeInfo(const TypeRef *TR,
874-
unsigned start,
875-
unsigned align) {
873+
const TypeInfo *TypeConverter::getClassInstanceTypeInfo(const TypeRef *TR,
874+
unsigned start,
875+
unsigned align) {
876876
const FieldDescriptor *FD = getBuilder().getFieldTypeInfo(TR);
877877
if (FD == nullptr)
878878
return nullptr;

stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,20 @@ swift_reflection_readIsaMask(SwiftReflectionContextRef ContextRef,
8080

8181
swift_typeref_t
8282
swift_reflection_typeRefForMetadata(SwiftReflectionContextRef ContextRef,
83-
uintptr_t metadata) {
83+
uintptr_t Metadata) {
8484
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
85-
auto TR = Context->readTypeFromMetadata(metadata);
85+
auto TR = Context->readTypeFromMetadata(Metadata);
86+
return reinterpret_cast<swift_typeref_t>(TR);
87+
}
88+
89+
swift_typeref_t
90+
swift_reflection_typeRefForInstance(SwiftReflectionContextRef ContextRef,
91+
uintptr_t Object) {
92+
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
93+
auto MetadataAddress = Context->readMetadataFromInstance(Object);
94+
if (!MetadataAddress.first)
95+
return 0;
96+
auto TR = Context->readTypeFromMetadata(MetadataAddress.second);
8697
return reinterpret_cast<swift_typeref_t>(TR);
8798
}
8899

@@ -208,7 +219,7 @@ swift_typeinfo_t
208219
swift_reflection_infoForMetadata(SwiftReflectionContextRef ContextRef,
209220
uintptr_t Metadata) {
210221
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
211-
auto *TI = Context->getInstanceTypeInfo(Metadata);
222+
auto *TI = Context->getMetadataTypeInfo(Metadata);
212223
return convertTypeInfo(TI);
213224
}
214225

@@ -217,7 +228,24 @@ swift_reflection_childOfMetadata(SwiftReflectionContextRef ContextRef,
217228
uintptr_t Metadata,
218229
unsigned Index) {
219230
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
220-
auto *TI = Context->getInstanceTypeInfo(Metadata);
231+
auto *TI = Context->getMetadataTypeInfo(Metadata);
232+
return convertChild(TI, Index);
233+
}
234+
235+
swift_typeinfo_t
236+
swift_reflection_infoForInstance(SwiftReflectionContextRef ContextRef,
237+
uintptr_t Object) {
238+
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
239+
auto *TI = Context->getInstanceTypeInfo(Object);
240+
return convertTypeInfo(TI);
241+
}
242+
243+
swift_childinfo_t
244+
swift_reflection_childOfInstance(SwiftReflectionContextRef ContextRef,
245+
uintptr_t Object,
246+
unsigned Index) {
247+
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
248+
auto *TI = Context->getInstanceTypeInfo(Object);
221249
return convertChild(TI, Index);
222250
}
223251

@@ -239,22 +267,33 @@ void swift_reflection_dumpTypeRef(swift_typeref_t OpaqueTypeRef) {
239267
}
240268
}
241269

270+
void swift_reflection_dumpInfoForTypeRef(SwiftReflectionContextRef ContextRef,
271+
swift_typeref_t OpaqueTypeRef) {
272+
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
273+
auto TR = reinterpret_cast<const TypeRef *>(OpaqueTypeRef);
274+
auto TI = Context->getTypeInfo(TR);
275+
if (TI == nullptr) {
276+
std::cerr << "<null type info>\n";
277+
} else {
278+
TI->dump();
279+
}
280+
}
281+
242282
void swift_reflection_dumpInfoForMetadata(SwiftReflectionContextRef ContextRef,
243283
uintptr_t Metadata) {
244284
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
245-
auto TI = Context->getInstanceTypeInfo(Metadata);
285+
auto TI = Context->getMetadataTypeInfo(Metadata);
246286
if (TI == nullptr) {
247287
std::cerr << "<null type info>\n";
248288
} else {
249289
TI->dump();
250290
}
251291
}
252292

253-
void swift_reflection_dumpInfoForTypeRef(SwiftReflectionContextRef ContextRef,
254-
swift_typeref_t OpaqueTypeRef) {
293+
void swift_reflection_dumpInfoForInstance(SwiftReflectionContextRef ContextRef,
294+
uintptr_t Object) {
255295
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
256-
auto TR = reinterpret_cast<const TypeRef *>(OpaqueTypeRef);
257-
auto TI = Context->getTypeInfo(TR);
296+
auto TI = Context->getInstanceTypeInfo(Object);
258297
if (TI == nullptr) {
259298
std::cerr << "<null type info>\n";
260299
} else {

tools/swift-reflection-test/swift-reflection-test.c

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -391,11 +391,6 @@ int doDumpHeapInstance(const char *BinaryFilename) {
391391
printf("Instance pointer in child address space: 0x%lx\n",
392392
instance);
393393

394-
uintptr_t isa;
395-
if (!PipeMemoryReader_readBytes(&Pipe, instance, (uint8_t*)&isa,
396-
sizeof(isa)))
397-
errorAndExit("Couldn't get heap object's metadata address");
398-
399394
size_t NumReflectionInfos = 0;
400395
const LocalReflectionInfo *Infos
401396
= PipeMemoryReader_receiveReflectionInfo(&Pipe, &NumReflectionInfos);
@@ -410,23 +405,14 @@ int doDumpHeapInstance(const char *BinaryFilename) {
410405
Info.reflstr);
411406
}
412407

413-
uintptr_t isaMask;
414-
if (!swift_reflection_readIsaMask(RC, &isaMask))
415-
errorAndExit("Couldn't read isa mask");
416-
printf("isa mask in child address space: 0x%lx\n", isaMask);
417-
418-
isa &= isaMask;
419-
420-
printf("Metadata pointer in child address space: 0x%lx\n\n", isa);
421-
422408
printf("Type reference:\n");
423409

424-
swift_typeref_t TR = swift_reflection_typeRefForMetadata(RC, isa);
410+
swift_typeref_t TR = swift_reflection_typeRefForInstance(RC, instance);
425411
swift_reflection_dumpTypeRef(TR);
426412
printf("\n");
427413

428414
printf("Type info:\n");
429-
swift_reflection_dumpInfoForMetadata(RC, isa);
415+
swift_reflection_dumpInfoForInstance(RC, instance);
430416
}
431417
}
432418

0 commit comments

Comments
 (0)