@@ -2397,6 +2397,8 @@ namespace {
2397
2397
2398
2398
// Conformance Cache.
2399
2399
2400
+ static void _initializeCallbacksToInspectDylib ();
2401
+
2400
2402
struct ConformanceState {
2401
2403
ConcurrentMap<size_t , ConformanceCacheEntry> Cache;
2402
2404
std::vector<ConformanceSection> SectionsToScan;
@@ -2405,24 +2407,18 @@ struct ConformanceState {
2405
2407
ConformanceState () {
2406
2408
SectionsToScan.reserve (16 );
2407
2409
pthread_mutex_init (&SectionsToScanLock, nullptr );
2410
+ _initializeCallbacksToInspectDylib ();
2408
2411
}
2409
2412
};
2410
2413
2411
2414
static Lazy<ConformanceState> Conformances;
2412
2415
2413
- // This variable is used to signal when a cache was generated and
2414
- // it is correct to avoid a new scan.
2415
- static unsigned ConformanceCacheGeneration = 0 ;
2416
-
2417
- void
2418
- swift::swift_registerProtocolConformances (const ProtocolConformanceRecord *begin,
2419
- const ProtocolConformanceRecord *end){
2420
- auto &C = Conformances.get ();
2421
-
2416
+ static void
2417
+ _registerProtocolConformances (ConformanceState &C,
2418
+ const ProtocolConformanceRecord *begin,
2419
+ const ProtocolConformanceRecord *end) {
2422
2420
pthread_mutex_lock (&C.SectionsToScanLock );
2423
-
2424
2421
C.SectionsToScan .push_back (ConformanceSection{begin, end});
2425
-
2426
2422
pthread_mutex_unlock (&C.SectionsToScanLock );
2427
2423
}
2428
2424
@@ -2437,7 +2433,10 @@ static void _addImageProtocolConformancesBlock(const uint8_t *conformances,
2437
2433
auto recordsEnd
2438
2434
= reinterpret_cast <const ProtocolConformanceRecord*>
2439
2435
(conformances + conformancesSize);
2440
- swift_registerProtocolConformances (recordsBegin, recordsEnd);
2436
+
2437
+ // Conformance cache should always be sufficiently initialized by this point.
2438
+ _registerProtocolConformances (Conformances.unsafeGetAlreadyInitialized (),
2439
+ recordsBegin, recordsEnd);
2441
2440
}
2442
2441
2443
2442
#if defined(__APPLE__) && defined(__MACH__)
@@ -2490,26 +2489,32 @@ static int _addImageProtocolConformances(struct dl_phdr_info *info,
2490
2489
}
2491
2490
#endif
2492
2491
2493
- static void installCallbacksToInspectDylib () {
2494
- static OnceToken_t token;
2495
- auto callback = [](void *) {
2496
- #if defined(__APPLE__) && defined(__MACH__)
2497
- // Install our dyld callback if we haven't already.
2498
- // Dyld will invoke this on our behalf for all images that have already
2499
- // been loaded.
2500
- _dyld_register_func_for_add_image (_addImageProtocolConformances);
2501
- #elif defined(__ELF__)
2502
- // Search the loaded dls. Unlike the above, this only searches the already
2503
- // loaded ones.
2504
- // FIXME: Find a way to have this continue to happen after.
2505
- // rdar://problem/19045112
2506
- dl_iterate_phdr (_addImageProtocolConformances, nullptr );
2507
- #else
2508
- # error No known mechanism to inspect dynamic libraries on this platform.
2509
- #endif
2510
- };
2511
-
2512
- SWIFT_ONCE_F (token, callback, nullptr );
2492
+ static void _initializeCallbacksToInspectDylib () {
2493
+ #if defined(__APPLE__) && defined(__MACH__)
2494
+ // Install our dyld callback.
2495
+ // Dyld will invoke this on our behalf for all images that have already
2496
+ // been loaded.
2497
+ _dyld_register_func_for_add_image (_addImageProtocolConformances);
2498
+ #elif defined(__ELF__)
2499
+ // Search the loaded dls. Unlike the above, this only searches the already
2500
+ // loaded ones.
2501
+ // FIXME: Find a way to have this continue to happen after.
2502
+ // rdar://problem/19045112
2503
+ dl_iterate_phdr (_addImageProtocolConformances, nullptr );
2504
+ #else
2505
+ # error No known mechanism to inspect dynamic libraries on this platform.
2506
+ #endif
2507
+ }
2508
+
2509
+ // This variable is used to signal when a cache was generated and
2510
+ // it is correct to avoid a new scan.
2511
+ static unsigned ConformanceCacheGeneration = 0 ;
2512
+
2513
+ void
2514
+ swift::swift_registerProtocolConformances (const ProtocolConformanceRecord *begin,
2515
+ const ProtocolConformanceRecord *end){
2516
+ auto &C = Conformances.get ();
2517
+ _registerProtocolConformances (C, begin, end);
2513
2518
}
2514
2519
2515
2520
static size_t hashTypeProtocolPair (const void *type,
@@ -2630,7 +2635,6 @@ swift::swift_conformsToProtocol(const Metadata *type,
2630
2635
2631
2636
// Install callbacks for tracking when a new dylib is loaded so we can
2632
2637
// scan it.
2633
- installCallbacksToInspectDylib ();
2634
2638
auto origType = type;
2635
2639
2636
2640
unsigned numSections = 0 ;
0 commit comments