Skip to content

Commit ebca730

Browse files
authored
Merge pull request #27274 from jckarter/detemplate-remote-ref
Reflection: Make RemoteRef template not depend on Runtime.
2 parents 96598d8 + 88a833f commit ebca730

File tree

2 files changed

+89
-80
lines changed

2 files changed

+89
-80
lines changed

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -531,8 +531,8 @@ class TypeRefBuilder {
531531
// underlying type if available.
532532
if (context->getKind() == ContextDescriptorKind::OpaqueType) {
533533
return Dem.createNode(
534-
Node::Kind::OpaqueTypeDescriptorSymbolicReference,
535-
(uintptr_t)context.getAddress());
534+
Node::Kind::OpaqueTypeDescriptorSymbolicReference,
535+
context.getAddressData());
536536
}
537537

538538
return reader.buildContextMangling(context, Dem);

include/swift/Remote/MetadataReader.h

Lines changed: 87 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -43,27 +43,25 @@ using TypeDecoder = swift::Demangle::TypeDecoder<BuilderType>;
4343

4444
/// A pointer to the local buffer of an object that also remembers the
4545
/// address at which it was stored remotely.
46-
template <typename Runtime, typename T>
46+
template <typename T>
4747
class RemoteRef {
48-
public:
49-
using StoredPointer = typename Runtime::StoredPointer;
50-
5148
private:
52-
StoredPointer Address;
49+
uint64_t Address;
5350
const T *LocalBuffer;
5451

5552
public:
5653
/*implicit*/
5754
RemoteRef(std::nullptr_t _)
5855
: Address(0), LocalBuffer(nullptr) {}
5956

57+
template<typename StoredPointer>
6058
explicit RemoteRef(StoredPointer address, const T *localBuffer)
61-
: Address(address), LocalBuffer(localBuffer) {}
59+
: Address((uint64_t)address), LocalBuffer(localBuffer) {}
6260

63-
StoredPointer getAddress() const {
61+
uint64_t getAddressData() const {
6462
return Address;
6563
}
66-
64+
6765
const T *getLocalBuffer() const {
6866
return LocalBuffer;
6967
}
@@ -76,6 +74,34 @@ class RemoteRef {
7674
assert(LocalBuffer);
7775
return LocalBuffer;
7876
}
77+
78+
bool operator==(RemoteRef<T> other) const {
79+
return Address == other.Address;
80+
}
81+
82+
bool operator!=(RemoteRef<T> other) const {
83+
return !operator==(other);
84+
}
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+
}
79105
};
80106

81107
/// A structure, designed for use with std::unique_ptr, which destroys
@@ -127,17 +153,15 @@ class MetadataReader {
127153
/// A cache of built types, keyed by the address of the type.
128154
std::unordered_map<StoredPointer, BuiltType> TypeCache;
129155

130-
using MetadataRef =
131-
RemoteRef<Runtime, TargetMetadata<Runtime>>;
156+
using MetadataRef = RemoteRef<TargetMetadata<Runtime>>;
132157
using OwnedMetadataRef =
133158
std::unique_ptr<const TargetMetadata<Runtime>, delete_with_free>;
134159

135160
/// A cache of read type metadata, keyed by the address of the metadata.
136161
std::unordered_map<StoredPointer, OwnedMetadataRef>
137162
MetadataCache;
138163

139-
using ContextDescriptorRef =
140-
RemoteRef<Runtime, TargetContextDescriptor<Runtime>>;
164+
using ContextDescriptorRef = RemoteRef<TargetContextDescriptor<Runtime>>;
141165
using OwnedContextDescriptorRef =
142166
std::unique_ptr<const TargetContextDescriptor<Runtime>,
143167
delete_with_free>;
@@ -1068,14 +1092,13 @@ class MetadataReader {
10681092
return ClassMetadataBounds::forSwiftRootClass();
10691093

10701094
auto rawSuperclass =
1071-
resolveNullableRelativeField(subclassRef,
1072-
subclass->getResilientSuperclass());
1095+
resolveRelativeField(subclassRef, subclass->getResilientSuperclass());
10731096
if (!rawSuperclass) {
10741097
return ClassMetadataBounds::forSwiftRootClass();
10751098
}
10761099

10771100
return forTypeReference<ClassMetadataBounds>(
1078-
subclass->getResilientSuperclassReferenceKind(), *rawSuperclass,
1101+
subclass->getResilientSuperclassReferenceKind(), rawSuperclass,
10791102
[&](ContextDescriptorRef superclass)
10801103
-> Optional<ClassMetadataBounds> {
10811104
if (!isa<TargetClassDescriptor<Runtime>>(superclass))
@@ -1166,7 +1189,7 @@ class MetadataReader {
11661189
return None;
11671190

11681191
auto addressOfGenericArgAddress =
1169-
(Meta.getAddress() +
1192+
(getAddress(Meta) +
11701193
*offsetToGenericArgs * sizeof(StoredPointer) +
11711194
index * sizeof(StoredPointer));
11721195

@@ -1237,31 +1260,6 @@ class MetadataReader {
12371260
}
12381261

12391262
protected:
1240-
template<typename Offset>
1241-
StoredPointer resolveRelativeOffset(StoredPointer targetAddress) {
1242-
Offset relative;
1243-
if (!Reader->readInteger(RemoteAddress(targetAddress), &relative))
1244-
return 0;
1245-
using SignedOffset = typename std::make_signed<Offset>::type;
1246-
using SignedPointer = typename std::make_signed<StoredPointer>::type;
1247-
auto signext = (SignedPointer)(SignedOffset)relative;
1248-
return targetAddress + signext;
1249-
}
1250-
1251-
template<typename Offset>
1252-
Optional<StoredPointer>
1253-
resolveNullableRelativeOffset(StoredPointer targetAddress) {
1254-
Offset relative;
1255-
if (!Reader->readInteger(RemoteAddress(targetAddress), &relative))
1256-
return None;
1257-
if (relative == 0)
1258-
return 0;
1259-
using SignedOffset = typename std::make_signed<Offset>::type;
1260-
using SignedPointer = typename std::make_signed<StoredPointer>::type;
1261-
auto signext = (SignedPointer)(SignedOffset)relative;
1262-
return targetAddress + signext;
1263-
}
1264-
12651263
template<typename Offset>
12661264
Optional<StoredPointer>
12671265
resolveNullableRelativeIndirectableOffset(StoredPointer targetAddress) {
@@ -1290,31 +1288,44 @@ class MetadataReader {
12901288
return resultAddress;
12911289
}
12921290

1293-
template<typename Base, typename Field>
1294-
StoredPointer resolveRelativeField(
1295-
RemoteRef<Runtime, Base> base, const Field &field) {
1296-
// Map the offset from within our local buffer to the remote address.
1297-
auto distance = (intptr_t)&field - (intptr_t)base.getLocalBuffer();
1298-
return resolveRelativeOffset<int32_t>(base.getAddress() + distance);
1291+
template<typename Base>
1292+
StoredPointer getAddress(RemoteRef<Base> base) {
1293+
return (StoredPointer)base.getAddressData();
12991294
}
13001295

13011296
template<typename Base, typename Field>
1302-
Optional<StoredPointer> resolveNullableRelativeField(
1303-
RemoteRef<Runtime, Base> base, const Field &field) {
1304-
// Map the offset from within our local buffer to the remote address.
1305-
auto distance = (intptr_t)&field - (intptr_t)base.getLocalBuffer();
1306-
1307-
return resolveNullableRelativeOffset<int32_t>(base.getAddress() + distance);
1297+
StoredPointer resolveRelativeField(
1298+
RemoteRef<Base> base, const Field &field) {
1299+
return (StoredPointer)base.resolveRelativeFieldData(field);
13081300
}
1309-
1301+
13101302
template<typename Base, typename Field>
1311-
Optional<StoredPointer> resolveNullableRelativeIndirectableField(
1312-
RemoteRef<Runtime, Base> base, const Field &field) {
1313-
// Map the offset from within our local buffer to the remote address.
1314-
auto distance = (intptr_t)&field - (intptr_t)base.getLocalBuffer();
1303+
Optional<StoredPointer> resolveRelativeIndirectableField(
1304+
RemoteRef<Base> base, const Field &field) {
1305+
auto fieldRef = base.getField(field);
1306+
int32_t offset;
1307+
memcpy(&offset, fieldRef.getLocalBuffer(), sizeof(int32_t));
13151308

1316-
return resolveNullableRelativeIndirectableOffset<int32_t>(
1317-
base.getAddress() + distance);
1309+
if (offset == 0)
1310+
return 0;
1311+
bool indirect = offset & 1;
1312+
offset &= ~1u;
1313+
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;
13181329
}
13191330

13201331
/// Given a pointer to an Objective-C class, try to read its class name.
@@ -1521,8 +1532,7 @@ class MetadataReader {
15211532
/// Returns None if there was an error reading the parent descriptor.
15221533
Optional<ContextDescriptorRef>
15231534
readParentContextDescriptor(ContextDescriptorRef base) {
1524-
auto parentAddress =
1525-
resolveNullableRelativeIndirectableField(base, base->Parent);
1535+
auto parentAddress = resolveRelativeIndirectableField(base, base->Parent);
15261536
if (!parentAddress)
15271537
return None;
15281538
if (!*parentAddress)
@@ -1838,7 +1848,7 @@ class MetadataReader {
18381848
const RelativeTargetProtocolDescriptorPointer<Runtime> &protocol) {
18391849
// Map the offset from within our local buffer to the remote address.
18401850
auto distance = (intptr_t)&protocol - (intptr_t)descriptor.getLocalBuffer();
1841-
StoredPointer targetAddress(descriptor.getAddress() + distance);
1851+
StoredPointer targetAddress(getAddress(descriptor) + distance);
18421852

18431853
// Read the relative offset.
18441854
int32_t relative;
@@ -2071,7 +2081,7 @@ class MetadataReader {
20712081
// address.
20722082
auto distance =
20732083
(intptr_t)&req.Layout - (intptr_t)descriptor.getLocalBuffer();
2074-
StoredPointer targetAddress(descriptor.getAddress() + distance);
2084+
StoredPointer targetAddress(getAddress(descriptor) + distance);
20752085

20762086
GenericRequirementLayoutKind kind;
20772087
if (!Reader->readBytes(RemoteAddress(targetAddress),
@@ -2106,7 +2116,7 @@ class MetadataReader {
21062116
// Use the remote address to identify the anonymous context.
21072117
char addressBuf[18];
21082118
snprintf(addressBuf, sizeof(addressBuf), "$%" PRIx64,
2109-
(uint64_t)descriptor.getAddress());
2119+
(uint64_t)descriptor.getAddressData());
21102120
auto anonNode = dem.createNode(Node::Kind::AnonymousContext);
21112121
CharVector addressStr;
21122122
addressStr.append(addressBuf, dem);
@@ -2269,7 +2279,7 @@ class MetadataReader {
22692279
if (!offsetToGenericArgs)
22702280
return {};
22712281

2272-
auto genericArgsAddr = metadata.getAddress()
2282+
auto genericArgsAddr = getAddress(metadata)
22732283
+ sizeof(StoredPointer) * *offsetToGenericArgs;
22742284

22752285
std::vector<BuiltType> builtSubsts;
@@ -2326,9 +2336,8 @@ class MetadataReader {
23262336

23272337
// If we've skipped an artificial subclasses, check the cache at
23282338
// the superclass. (This also protects against recursion.)
2329-
if (skipArtificialSubclasses &&
2330-
metadata.getAddress() != origMetadata.getAddress()) {
2331-
auto it = TypeCache.find(metadata.getAddress());
2339+
if (skipArtificialSubclasses && metadata != origMetadata) {
2340+
auto it = TypeCache.find(getAddress(metadata));
23322341
if (it != TypeCache.end())
23332342
return it->second;
23342343
}
@@ -2358,13 +2367,12 @@ class MetadataReader {
23582367
if (!nominal)
23592368
return BuiltType();
23602369

2361-
TypeCache[metadata.getAddress()] = nominal;
2370+
TypeCache[getAddress(metadata)] = nominal;
23622371

23632372
// If we've skipped an artificial subclass, remove the
23642373
// recursion-protection entry we made for it.
2365-
if (skipArtificialSubclasses &&
2366-
metadata.getAddress() != origMetadata.getAddress()) {
2367-
TypeCache.erase(origMetadata.getAddress());
2374+
if (skipArtificialSubclasses && metadata != origMetadata) {
2375+
TypeCache.erase(getAddress(origMetadata));
23682376
}
23692377

23702378
return nominal;
@@ -2377,7 +2385,8 @@ class MetadataReader {
23772385
return readNominalTypeFromMetadata(origMetadata, skipArtificialSubclasses);
23782386

23792387
std::string className;
2380-
if (!readObjCClassName(origMetadata.getAddress(), className))
2388+
auto origMetadataPtr = getAddress(origMetadata);
2389+
if (!readObjCClassName(origMetadataPtr, className))
23812390
return BuiltType();
23822391

23832392
BuiltType BuiltObjCClass = Builder.createObjCClassType(std::move(className));
@@ -2390,7 +2399,7 @@ class MetadataReader {
23902399
skipArtificialSubclasses);
23912400
}
23922401

2393-
TypeCache[origMetadata.getAddress()] = BuiltObjCClass;
2402+
TypeCache[origMetadataPtr] = BuiltObjCClass;
23942403
return BuiltObjCClass;
23952404
}
23962405

@@ -2583,11 +2592,11 @@ class MetadataReader {
25832592
} // end namespace swift
25842593

25852594
namespace llvm {
2586-
template<typename Runtime, typename T>
2587-
struct simplify_type<swift::remote::RemoteRef<Runtime, T>> {
2595+
template<typename T>
2596+
struct simplify_type<swift::remote::RemoteRef<T>> {
25882597
using SimpleType = const T *;
25892598
static SimpleType
2590-
getSimplifiedValue(swift::remote::RemoteRef<Runtime, T> value) {
2599+
getSimplifiedValue(swift::remote::RemoteRef<T> value) {
25912600
return value.getLocalBuffer();
25922601
}
25932602
};

0 commit comments

Comments
 (0)