@@ -200,14 +200,14 @@ namespace {
200
200
private:
201
201
const void *Type;
202
202
const ProtocolDescriptor *Proto;
203
- std::atomic<const WitnessTable *> Table ;
203
+ std::atomic<const ProtocolConformanceDescriptor *> Description ;
204
204
std::atomic<size_t > FailureGeneration;
205
205
206
206
public:
207
207
ConformanceCacheEntry (ConformanceCacheKey key,
208
- const WitnessTable *table ,
208
+ const ProtocolConformanceDescriptor *description ,
209
209
size_t failureGeneration)
210
- : Type(key.Type), Proto(key.Proto), Table(table ),
210
+ : Type(key.Type), Proto(key.Proto), Description(description ),
211
211
FailureGeneration (failureGeneration) {
212
212
}
213
213
@@ -227,22 +227,22 @@ namespace {
227
227
}
228
228
229
229
bool isSuccessful () const {
230
- return Table .load (std::memory_order_relaxed) != nullptr ;
230
+ return Description .load (std::memory_order_relaxed) != nullptr ;
231
231
}
232
232
233
- void makeSuccessful (const WitnessTable *table ) {
234
- Table .store (table , std::memory_order_release);
233
+ void makeSuccessful (const ProtocolConformanceDescriptor *description ) {
234
+ Description .store (description , std::memory_order_release);
235
235
}
236
236
237
237
void updateFailureGeneration (size_t failureGeneration) {
238
238
assert (!isSuccessful ());
239
239
FailureGeneration.store (failureGeneration, std::memory_order_relaxed);
240
240
}
241
-
242
- // / Get the cached witness table , if successful.
243
- const WitnessTable * getWitnessTable () const {
241
+
242
+ // / Get the cached conformance descriptor , if successful.
243
+ const ProtocolConformanceDescriptor * getDescription () const {
244
244
assert (isSuccessful ());
245
- return Table .load (std::memory_order_acquire);
245
+ return Description .load (std::memory_order_acquire);
246
246
}
247
247
248
248
// / Get the generation in which this lookup failed.
@@ -263,21 +263,22 @@ struct ConformanceState {
263
263
}
264
264
265
265
void cacheSuccess (const void *type, const ProtocolDescriptor *proto,
266
- const WitnessTable *witness ) {
266
+ const ProtocolConformanceDescriptor *description ) {
267
267
auto result = Cache.getOrInsert (ConformanceCacheKey (type, proto),
268
- witness , 0 );
268
+ description , 0 );
269
269
270
270
// If the entry was already present, we may need to update it.
271
271
if (!result.second ) {
272
- result.first ->makeSuccessful (witness );
272
+ result.first ->makeSuccessful (description );
273
273
}
274
274
}
275
275
276
276
void cacheFailure (const void *type, const ProtocolDescriptor *proto,
277
277
size_t failureGeneration) {
278
- auto result = Cache.getOrInsert (ConformanceCacheKey (type, proto),
279
- (const WitnessTable *) nullptr ,
280
- failureGeneration);
278
+ auto result =
279
+ Cache.getOrInsert (ConformanceCacheKey (type, proto),
280
+ (const ProtocolConformanceDescriptor *) nullptr ,
281
+ failureGeneration);
281
282
282
283
// If the entry was already present, we may need to update it.
283
284
if (!result.second ) {
@@ -344,21 +345,22 @@ swift::swift_registerProtocolConformances(const ProtocolConformanceRecord *begin
344
345
345
346
346
347
struct ConformanceCacheResult {
347
- // true if witnessTable is an authoritative result as-is.
348
+ // true if description is an authoritative result as-is.
348
349
// false if more searching is required (for example, because a cached
349
350
// failure was returned in failureEntry but it is out-of-date.
350
351
bool isAuthoritative;
351
352
352
- // The matching witness table, or null if no cached conformance was found.
353
- const WitnessTable *witnessTable;
353
+ // The matching conformance descriptor, or null if no cached conformance
354
+ // was found.
355
+ const ProtocolConformanceDescriptor *description;
354
356
355
357
// If the search fails, this may be the negative cache entry for the
356
358
// queried type itself. This entry may be null or out-of-date.
357
359
ConformanceCacheEntry *failureEntry;
358
360
359
361
static ConformanceCacheResult
360
- cachedSuccess (const WitnessTable *table ) {
361
- return ConformanceCacheResult { true , table , nullptr };
362
+ cachedSuccess (const ProtocolConformanceDescriptor *description ) {
363
+ return ConformanceCacheResult { true , description , nullptr };
362
364
}
363
365
364
366
static ConformanceCacheResult
@@ -381,7 +383,7 @@ static const void *getConformanceCacheTypeKey(const Metadata *type) {
381
383
return type;
382
384
}
383
385
384
- // / Search for a witness table in the ConformanceCache.
386
+ // / Search for a conformance descriptor in the ConformanceCache.
385
387
static
386
388
ConformanceCacheResult
387
389
searchInConformanceCache (const Metadata *type,
@@ -396,7 +398,7 @@ searchInConformanceCache(const Metadata *type,
396
398
if (auto *Value = C.findCached (type, protocol)) {
397
399
if (Value->isSuccessful ()) {
398
400
// Found a conformance on the type or some superclass. Return it.
399
- return ConformanceCacheResult::cachedSuccess (Value->getWitnessTable ());
401
+ return ConformanceCacheResult::cachedSuccess (Value->getDescription ());
400
402
}
401
403
402
404
// Found a negative cache entry.
@@ -438,7 +440,7 @@ searchInConformanceCache(const Metadata *type,
438
440
// Hash and lookup the type-protocol pair in the cache.
439
441
if (auto *Value = C.findCached (typeKey, protocol)) {
440
442
if (Value->isSuccessful ())
441
- return ConformanceCacheResult::cachedSuccess (Value->getWitnessTable ());
443
+ return ConformanceCacheResult::cachedSuccess (Value->getDescription ());
442
444
443
445
// We don't try to cache negative responses for generic
444
446
// patterns.
@@ -530,17 +532,17 @@ namespace {
530
532
};
531
533
}
532
534
533
- static const WitnessTable *
534
- swift_conformsToProtocolImpl (const Metadata * const type,
535
- const ProtocolDescriptor *protocol) {
535
+ const ProtocolConformanceDescriptor *
536
+ swift::_conformsToSwiftProtocol (const Metadata * const type,
537
+ const ProtocolDescriptor *protocol) {
536
538
auto &C = Conformances.get ();
537
539
538
540
// See if we have a cached conformance. The ConcurrentMap data structure
539
541
// allows us to insert and search the map concurrently without locking.
540
542
auto FoundConformance = searchInConformanceCache (type, protocol);
541
543
// If the result (positive or negative) is authoritative, return it.
542
544
if (FoundConformance.isAuthoritative )
543
- return FoundConformance.witnessTable ;
545
+ return FoundConformance.description ;
544
546
545
547
auto failureEntry = FoundConformance.failureEntry ;
546
548
@@ -560,16 +562,6 @@ swift_conformsToProtocolImpl(const Metadata * const type,
560
562
return nullptr ;
561
563
}
562
564
563
- // / Local function to retrieve the witness table and record the result.
564
- auto recordWitnessTable = [&](const ProtocolConformanceDescriptor &descriptor,
565
- const Metadata *type) {
566
- auto witnessTable = descriptor.getWitnessTable (type);
567
- if (witnessTable)
568
- C.cacheSuccess (type, protocol, witnessTable);
569
- else
570
- C.cacheFailure (type, protocol, snapshot.count ());
571
- };
572
-
573
565
// Really scan conformance records.
574
566
for (size_t i = startIndex; i < endIndex; i++) {
575
567
auto §ion = snapshot.Start [i];
@@ -588,23 +580,33 @@ swift_conformsToProtocolImpl(const Metadata * const type,
588
580
if (!matchingType)
589
581
matchingType = type;
590
582
591
- recordWitnessTable (descriptor, matchingType );
583
+ C. cacheSuccess (matchingType, protocol, &descriptor );
592
584
}
593
585
}
594
586
}
595
587
596
588
// Conformance scan is complete.
597
- // Search the cache once more, and this time update the cache if necessary.
598
589
590
+ // Search the cache once more, and this time update the cache if necessary.
599
591
FoundConformance = searchInConformanceCache (type, protocol);
600
592
if (FoundConformance.isAuthoritative ) {
601
- return FoundConformance.witnessTable ;
593
+ return FoundConformance.description ;
602
594
} else {
603
595
C.cacheFailure (type, protocol, snapshot.count ());
604
596
return nullptr ;
605
597
}
606
598
}
607
599
600
+ static const WitnessTable *
601
+ swift_conformsToProtocolImpl (const Metadata * const type,
602
+ const ProtocolDescriptor *protocol) {
603
+ auto description = _conformsToSwiftProtocol (type, protocol);
604
+ if (!description)
605
+ return nullptr ;
606
+
607
+ return description->getWitnessTable (type);
608
+ }
609
+
608
610
const ContextDescriptor *
609
611
swift::_searchConformancesByMangledTypeName (Demangle::NodePointer node) {
610
612
auto &C = Conformances.get ();
0 commit comments