Skip to content

Commit 88a833f

Browse files
committed
Reflection: Move resolveRelativeField functionality onto RemoteRef
Resolving a direct relative reference given a RemoteRef doesn't need the MetadataReader, since the offset should already be in the local buffer; we can add it to RemoteRef's saved remote address and get a new remote address. Refactor the API to make as much as possible of it available directly on RemoteRef.
1 parent f1cb0d1 commit 88a833f

File tree

2 files changed

+62
-65
lines changed

2 files changed

+62
-65
lines changed

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ class TypeRefBuilder {
532532
if (context->getKind() == ContextDescriptorKind::OpaqueType) {
533533
return Dem.createNode(
534534
Node::Kind::OpaqueTypeDescriptorSymbolicReference,
535-
(uintptr_t)context.template getAddress<Runtime>());
535+
context.getAddressData());
536536
}
537537

538538
return reader.buildContextMangling(context, Dem);

include/swift/Remote/MetadataReader.h

Lines changed: 61 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,6 @@ class RemoteRef {
6262
return Address;
6363
}
6464

65-
template<typename Runtime>
66-
typename Runtime::StoredPointer getAddress() const {
67-
return (typename Runtime::StoredPointer)getAddressData();
68-
}
69-
7065
const T *getLocalBuffer() const {
7166
return LocalBuffer;
7267
}
@@ -87,6 +82,26 @@ class RemoteRef {
8782
bool operator!=(RemoteRef<T> other) const {
8883
return !operator==(other);
8984
}
85+
86+
/// Project a reference for a field. The field must be projected from the same
87+
/// LocalBuffer pointer as this RemoteRef.
88+
template<typename U>
89+
RemoteRef<U> getField(U &field) const {
90+
auto offset = (intptr_t)&field - (intptr_t)LocalBuffer;
91+
return RemoteRef<U>((uint64_t)(Address + (int64_t)offset), &field);
92+
}
93+
94+
/// Resolve the remote address of a relative offset stored at the remote address.
95+
uint64_t resolveRelativeAddressData() const {
96+
int32_t offset;
97+
memcpy(&offset, LocalBuffer, sizeof(int32_t));
98+
return Address + (int64_t)offset;
99+
}
100+
101+
template<typename U>
102+
uint64_t resolveRelativeFieldData(U &field) const {
103+
return getField(field).resolveRelativeAddressData();
104+
}
90105
};
91106

92107
/// A structure, designed for use with std::unique_ptr, which destroys
@@ -1077,14 +1092,13 @@ class MetadataReader {
10771092
return ClassMetadataBounds::forSwiftRootClass();
10781093

10791094
auto rawSuperclass =
1080-
resolveNullableRelativeField(subclassRef,
1081-
subclass->getResilientSuperclass());
1095+
resolveRelativeField(subclassRef, subclass->getResilientSuperclass());
10821096
if (!rawSuperclass) {
10831097
return ClassMetadataBounds::forSwiftRootClass();
10841098
}
10851099

10861100
return forTypeReference<ClassMetadataBounds>(
1087-
subclass->getResilientSuperclassReferenceKind(), *rawSuperclass,
1101+
subclass->getResilientSuperclassReferenceKind(), rawSuperclass,
10881102
[&](ContextDescriptorRef superclass)
10891103
-> Optional<ClassMetadataBounds> {
10901104
if (!isa<TargetClassDescriptor<Runtime>>(superclass))
@@ -1175,7 +1189,7 @@ class MetadataReader {
11751189
return None;
11761190

11771191
auto addressOfGenericArgAddress =
1178-
(Meta.template getAddress<Runtime>() +
1192+
(getAddress(Meta) +
11791193
*offsetToGenericArgs * sizeof(StoredPointer) +
11801194
index * sizeof(StoredPointer));
11811195

@@ -1246,31 +1260,6 @@ class MetadataReader {
12461260
}
12471261

12481262
protected:
1249-
template<typename Offset>
1250-
StoredPointer resolveRelativeOffset(StoredPointer targetAddress) {
1251-
Offset relative;
1252-
if (!Reader->readInteger(RemoteAddress(targetAddress), &relative))
1253-
return 0;
1254-
using SignedOffset = typename std::make_signed<Offset>::type;
1255-
using SignedPointer = typename std::make_signed<StoredPointer>::type;
1256-
auto signext = (SignedPointer)(SignedOffset)relative;
1257-
return targetAddress + signext;
1258-
}
1259-
1260-
template<typename Offset>
1261-
Optional<StoredPointer>
1262-
resolveNullableRelativeOffset(StoredPointer targetAddress) {
1263-
Offset relative;
1264-
if (!Reader->readInteger(RemoteAddress(targetAddress), &relative))
1265-
return None;
1266-
if (relative == 0)
1267-
return 0;
1268-
using SignedOffset = typename std::make_signed<Offset>::type;
1269-
using SignedPointer = typename std::make_signed<StoredPointer>::type;
1270-
auto signext = (SignedPointer)(SignedOffset)relative;
1271-
return targetAddress + signext;
1272-
}
1273-
12741263
template<typename Offset>
12751264
Optional<StoredPointer>
12761265
resolveNullableRelativeIndirectableOffset(StoredPointer targetAddress) {
@@ -1299,33 +1288,44 @@ class MetadataReader {
12991288
return resultAddress;
13001289
}
13011290

1302-
template<typename Base, typename Field>
1303-
StoredPointer resolveRelativeField(
1304-
RemoteRef<Base> base, const Field &field) {
1305-
// Map the offset from within our local buffer to the remote address.
1306-
auto distance = (intptr_t)&field - (intptr_t)base.getLocalBuffer();
1307-
return resolveRelativeOffset<int32_t>(
1308-
base.template getAddress<Runtime>() + distance);
1291+
template<typename Base>
1292+
StoredPointer getAddress(RemoteRef<Base> base) {
1293+
return (StoredPointer)base.getAddressData();
13091294
}
13101295

13111296
template<typename Base, typename Field>
1312-
Optional<StoredPointer> resolveNullableRelativeField(
1297+
StoredPointer resolveRelativeField(
13131298
RemoteRef<Base> base, const Field &field) {
1314-
// Map the offset from within our local buffer to the remote address.
1315-
auto distance = (intptr_t)&field - (intptr_t)base.getLocalBuffer();
1316-
1317-
return resolveNullableRelativeOffset<int32_t>(
1318-
base.template getAddress<Runtime>() + distance);
1299+
return (StoredPointer)base.resolveRelativeFieldData(field);
13191300
}
1320-
1301+
13211302
template<typename Base, typename Field>
1322-
Optional<StoredPointer> resolveNullableRelativeIndirectableField(
1303+
Optional<StoredPointer> resolveRelativeIndirectableField(
13231304
RemoteRef<Base> base, const Field &field) {
1324-
// Map the offset from within our local buffer to the remote address.
1325-
auto distance = (intptr_t)&field - (intptr_t)base.getLocalBuffer();
1305+
auto fieldRef = base.getField(field);
1306+
int32_t offset;
1307+
memcpy(&offset, fieldRef.getLocalBuffer(), sizeof(int32_t));
1308+
1309+
if (offset == 0)
1310+
return 0;
1311+
bool indirect = offset & 1;
1312+
offset &= ~1u;
13261313

1327-
return resolveNullableRelativeIndirectableOffset<int32_t>(
1328-
base.template getAddress<Runtime>() + distance);
1314+
using SignedPointer = typename std::make_signed<StoredPointer>::type;
1315+
1316+
StoredPointer resultAddress = getAddress(fieldRef) + (SignedPointer)offset;
1317+
1318+
// Low bit set in the offset indicates that the offset leads to the absolute
1319+
// address in memory.
1320+
if (indirect) {
1321+
if (!Reader->readBytes(RemoteAddress(resultAddress),
1322+
(uint8_t *)&resultAddress,
1323+
sizeof(StoredPointer))) {
1324+
return None;
1325+
}
1326+
}
1327+
1328+
return resultAddress;
13291329
}
13301330

13311331
/// Given a pointer to an Objective-C class, try to read its class name.
@@ -1532,8 +1532,7 @@ class MetadataReader {
15321532
/// Returns None if there was an error reading the parent descriptor.
15331533
Optional<ContextDescriptorRef>
15341534
readParentContextDescriptor(ContextDescriptorRef base) {
1535-
auto parentAddress =
1536-
resolveNullableRelativeIndirectableField(base, base->Parent);
1535+
auto parentAddress = resolveRelativeIndirectableField(base, base->Parent);
15371536
if (!parentAddress)
15381537
return None;
15391538
if (!*parentAddress)
@@ -1849,8 +1848,7 @@ class MetadataReader {
18491848
const RelativeTargetProtocolDescriptorPointer<Runtime> &protocol) {
18501849
// Map the offset from within our local buffer to the remote address.
18511850
auto distance = (intptr_t)&protocol - (intptr_t)descriptor.getLocalBuffer();
1852-
StoredPointer targetAddress(
1853-
descriptor.template getAddress<Runtime>() + distance);
1851+
StoredPointer targetAddress(getAddress(descriptor) + distance);
18541852

18551853
// Read the relative offset.
18561854
int32_t relative;
@@ -2083,8 +2081,7 @@ class MetadataReader {
20832081
// address.
20842082
auto distance =
20852083
(intptr_t)&req.Layout - (intptr_t)descriptor.getLocalBuffer();
2086-
StoredPointer targetAddress(
2087-
descriptor.template getAddress<Runtime>() + distance);
2084+
StoredPointer targetAddress(getAddress(descriptor) + distance);
20882085

20892086
GenericRequirementLayoutKind kind;
20902087
if (!Reader->readBytes(RemoteAddress(targetAddress),
@@ -2282,7 +2279,7 @@ class MetadataReader {
22822279
if (!offsetToGenericArgs)
22832280
return {};
22842281

2285-
auto genericArgsAddr = metadata.template getAddress<Runtime>()
2282+
auto genericArgsAddr = getAddress(metadata)
22862283
+ sizeof(StoredPointer) * *offsetToGenericArgs;
22872284

22882285
std::vector<BuiltType> builtSubsts;
@@ -2340,7 +2337,7 @@ class MetadataReader {
23402337
// If we've skipped an artificial subclasses, check the cache at
23412338
// the superclass. (This also protects against recursion.)
23422339
if (skipArtificialSubclasses && metadata != origMetadata) {
2343-
auto it = TypeCache.find(metadata.template getAddress<Runtime>());
2340+
auto it = TypeCache.find(getAddress(metadata));
23442341
if (it != TypeCache.end())
23452342
return it->second;
23462343
}
@@ -2370,12 +2367,12 @@ class MetadataReader {
23702367
if (!nominal)
23712368
return BuiltType();
23722369

2373-
TypeCache[metadata.template getAddress<Runtime>()] = nominal;
2370+
TypeCache[getAddress(metadata)] = nominal;
23742371

23752372
// If we've skipped an artificial subclass, remove the
23762373
// recursion-protection entry we made for it.
23772374
if (skipArtificialSubclasses && metadata != origMetadata) {
2378-
TypeCache.erase(origMetadata.template getAddress<Runtime>());
2375+
TypeCache.erase(getAddress(origMetadata));
23792376
}
23802377

23812378
return nominal;
@@ -2388,7 +2385,7 @@ class MetadataReader {
23882385
return readNominalTypeFromMetadata(origMetadata, skipArtificialSubclasses);
23892386

23902387
std::string className;
2391-
auto origMetadataPtr = origMetadata.template getAddress<Runtime>();
2388+
auto origMetadataPtr = getAddress(origMetadata);
23922389
if (!readObjCClassName(origMetadataPtr, className))
23932390
return BuiltType();
23942391

0 commit comments

Comments
 (0)