@@ -43,27 +43,25 @@ using TypeDecoder = swift::Demangle::TypeDecoder<BuilderType>;
43
43
44
44
// / A pointer to the local buffer of an object that also remembers the
45
45
// / address at which it was stored remotely.
46
- template <typename Runtime, typename T>
46
+ template <typename T>
47
47
class RemoteRef {
48
- public:
49
- using StoredPointer = typename Runtime::StoredPointer;
50
-
51
48
private:
52
- StoredPointer Address;
49
+ uint64_t Address;
53
50
const T *LocalBuffer;
54
51
55
52
public:
56
53
/* implicit*/
57
54
RemoteRef (std::nullptr_t _)
58
55
: Address(0 ), LocalBuffer(nullptr ) {}
59
56
57
+ template <typename StoredPointer>
60
58
explicit RemoteRef (StoredPointer address, const T *localBuffer)
61
- : Address(address), LocalBuffer(localBuffer) {}
59
+ : Address(( uint64_t ) address), LocalBuffer(localBuffer) {}
62
60
63
- StoredPointer getAddress () const {
61
+ uint64_t getAddressData () const {
64
62
return Address;
65
63
}
66
-
64
+
67
65
const T *getLocalBuffer () const {
68
66
return LocalBuffer;
69
67
}
@@ -76,6 +74,34 @@ class RemoteRef {
76
74
assert (LocalBuffer);
77
75
return LocalBuffer;
78
76
}
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
+ }
79
105
};
80
106
81
107
// / A structure, designed for use with std::unique_ptr, which destroys
@@ -127,17 +153,15 @@ class MetadataReader {
127
153
// / A cache of built types, keyed by the address of the type.
128
154
std::unordered_map<StoredPointer, BuiltType> TypeCache;
129
155
130
- using MetadataRef =
131
- RemoteRef<Runtime, TargetMetadata<Runtime>>;
156
+ using MetadataRef = RemoteRef<TargetMetadata<Runtime>>;
132
157
using OwnedMetadataRef =
133
158
std::unique_ptr<const TargetMetadata<Runtime>, delete_with_free>;
134
159
135
160
// / A cache of read type metadata, keyed by the address of the metadata.
136
161
std::unordered_map<StoredPointer, OwnedMetadataRef>
137
162
MetadataCache;
138
163
139
- using ContextDescriptorRef =
140
- RemoteRef<Runtime, TargetContextDescriptor<Runtime>>;
164
+ using ContextDescriptorRef = RemoteRef<TargetContextDescriptor<Runtime>>;
141
165
using OwnedContextDescriptorRef =
142
166
std::unique_ptr<const TargetContextDescriptor<Runtime>,
143
167
delete_with_free>;
@@ -1068,14 +1092,13 @@ class MetadataReader {
1068
1092
return ClassMetadataBounds::forSwiftRootClass ();
1069
1093
1070
1094
auto rawSuperclass =
1071
- resolveNullableRelativeField (subclassRef,
1072
- subclass->getResilientSuperclass ());
1095
+ resolveRelativeField (subclassRef, subclass->getResilientSuperclass ());
1073
1096
if (!rawSuperclass) {
1074
1097
return ClassMetadataBounds::forSwiftRootClass ();
1075
1098
}
1076
1099
1077
1100
return forTypeReference<ClassMetadataBounds>(
1078
- subclass->getResilientSuperclassReferenceKind (), * rawSuperclass,
1101
+ subclass->getResilientSuperclassReferenceKind (), rawSuperclass,
1079
1102
[&](ContextDescriptorRef superclass)
1080
1103
-> Optional<ClassMetadataBounds> {
1081
1104
if (!isa<TargetClassDescriptor<Runtime>>(superclass))
@@ -1166,7 +1189,7 @@ class MetadataReader {
1166
1189
return None;
1167
1190
1168
1191
auto addressOfGenericArgAddress =
1169
- (Meta. getAddress () +
1192
+ (getAddress (Meta ) +
1170
1193
*offsetToGenericArgs * sizeof (StoredPointer) +
1171
1194
index * sizeof (StoredPointer));
1172
1195
@@ -1237,31 +1260,6 @@ class MetadataReader {
1237
1260
}
1238
1261
1239
1262
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
-
1265
1263
template <typename Offset>
1266
1264
Optional<StoredPointer>
1267
1265
resolveNullableRelativeIndirectableOffset (StoredPointer targetAddress) {
@@ -1290,31 +1288,44 @@ class MetadataReader {
1290
1288
return resultAddress;
1291
1289
}
1292
1290
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 ();
1299
1294
}
1300
1295
1301
1296
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);
1308
1300
}
1309
-
1301
+
1310
1302
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 ));
1315
1308
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;
1318
1329
}
1319
1330
1320
1331
// / Given a pointer to an Objective-C class, try to read its class name.
@@ -1521,8 +1532,7 @@ class MetadataReader {
1521
1532
// / Returns None if there was an error reading the parent descriptor.
1522
1533
Optional<ContextDescriptorRef>
1523
1534
readParentContextDescriptor (ContextDescriptorRef base) {
1524
- auto parentAddress =
1525
- resolveNullableRelativeIndirectableField (base, base->Parent );
1535
+ auto parentAddress = resolveRelativeIndirectableField (base, base->Parent );
1526
1536
if (!parentAddress)
1527
1537
return None;
1528
1538
if (!*parentAddress)
@@ -1838,7 +1848,7 @@ class MetadataReader {
1838
1848
const RelativeTargetProtocolDescriptorPointer<Runtime> &protocol) {
1839
1849
// Map the offset from within our local buffer to the remote address.
1840
1850
auto distance = (intptr_t )&protocol - (intptr_t )descriptor.getLocalBuffer ();
1841
- StoredPointer targetAddress (descriptor. getAddress () + distance);
1851
+ StoredPointer targetAddress (getAddress (descriptor ) + distance);
1842
1852
1843
1853
// Read the relative offset.
1844
1854
int32_t relative;
@@ -2071,7 +2081,7 @@ class MetadataReader {
2071
2081
// address.
2072
2082
auto distance =
2073
2083
(intptr_t )&req.Layout - (intptr_t )descriptor.getLocalBuffer ();
2074
- StoredPointer targetAddress (descriptor. getAddress () + distance);
2084
+ StoredPointer targetAddress (getAddress (descriptor ) + distance);
2075
2085
2076
2086
GenericRequirementLayoutKind kind;
2077
2087
if (!Reader->readBytes (RemoteAddress (targetAddress),
@@ -2106,7 +2116,7 @@ class MetadataReader {
2106
2116
// Use the remote address to identify the anonymous context.
2107
2117
char addressBuf[18 ];
2108
2118
snprintf (addressBuf, sizeof (addressBuf), " $%" PRIx64,
2109
- (uint64_t )descriptor.getAddress ());
2119
+ (uint64_t )descriptor.getAddressData ());
2110
2120
auto anonNode = dem.createNode (Node::Kind::AnonymousContext);
2111
2121
CharVector addressStr;
2112
2122
addressStr.append (addressBuf, dem);
@@ -2269,7 +2279,7 @@ class MetadataReader {
2269
2279
if (!offsetToGenericArgs)
2270
2280
return {};
2271
2281
2272
- auto genericArgsAddr = metadata. getAddress ()
2282
+ auto genericArgsAddr = getAddress (metadata )
2273
2283
+ sizeof (StoredPointer) * *offsetToGenericArgs;
2274
2284
2275
2285
std::vector<BuiltType> builtSubsts;
@@ -2326,9 +2336,8 @@ class MetadataReader {
2326
2336
2327
2337
// If we've skipped an artificial subclasses, check the cache at
2328
2338
// 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));
2332
2341
if (it != TypeCache.end ())
2333
2342
return it->second ;
2334
2343
}
@@ -2358,13 +2367,12 @@ class MetadataReader {
2358
2367
if (!nominal)
2359
2368
return BuiltType ();
2360
2369
2361
- TypeCache[metadata. getAddress ()] = nominal;
2370
+ TypeCache[getAddress (metadata )] = nominal;
2362
2371
2363
2372
// If we've skipped an artificial subclass, remove the
2364
2373
// 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));
2368
2376
}
2369
2377
2370
2378
return nominal;
@@ -2377,7 +2385,8 @@ class MetadataReader {
2377
2385
return readNominalTypeFromMetadata (origMetadata, skipArtificialSubclasses);
2378
2386
2379
2387
std::string className;
2380
- if (!readObjCClassName (origMetadata.getAddress (), className))
2388
+ auto origMetadataPtr = getAddress (origMetadata);
2389
+ if (!readObjCClassName (origMetadataPtr, className))
2381
2390
return BuiltType ();
2382
2391
2383
2392
BuiltType BuiltObjCClass = Builder.createObjCClassType (std::move (className));
@@ -2390,7 +2399,7 @@ class MetadataReader {
2390
2399
skipArtificialSubclasses);
2391
2400
}
2392
2401
2393
- TypeCache[origMetadata. getAddress () ] = BuiltObjCClass;
2402
+ TypeCache[origMetadataPtr ] = BuiltObjCClass;
2394
2403
return BuiltObjCClass;
2395
2404
}
2396
2405
@@ -2583,11 +2592,11 @@ class MetadataReader {
2583
2592
} // end namespace swift
2584
2593
2585
2594
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>> {
2588
2597
using SimpleType = const T *;
2589
2598
static SimpleType
2590
- getSimplifiedValue (swift::remote::RemoteRef<Runtime, T> value) {
2599
+ getSimplifiedValue (swift::remote::RemoteRef<T> value) {
2591
2600
return value.getLocalBuffer ();
2592
2601
}
2593
2602
};
0 commit comments