Skip to content

Commit d0be84e

Browse files
committed
Runtime: Refactor conformance cache initialization to include installation of the dyld callbacks.
This more cleanly groups together the initialization steps needed to warm up the conformance cache, so redundant work doesn't need to be done by other interested parties (such as the type-by-name lookup @lhoward's working on).
1 parent e210532 commit d0be84e

File tree

1 file changed

+37
-33
lines changed

1 file changed

+37
-33
lines changed

stdlib/public/runtime/Casting.cpp

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2397,6 +2397,8 @@ namespace {
23972397

23982398
// Conformance Cache.
23992399

2400+
static void _initializeCallbacksToInspectDylib();
2401+
24002402
struct ConformanceState {
24012403
ConcurrentMap<size_t, ConformanceCacheEntry> Cache;
24022404
std::vector<ConformanceSection> SectionsToScan;
@@ -2405,24 +2407,18 @@ struct ConformanceState {
24052407
ConformanceState() {
24062408
SectionsToScan.reserve(16);
24072409
pthread_mutex_init(&SectionsToScanLock, nullptr);
2410+
_initializeCallbacksToInspectDylib();
24082411
}
24092412
};
24102413

24112414
static Lazy<ConformanceState> Conformances;
24122415

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) {
24222420
pthread_mutex_lock(&C.SectionsToScanLock);
2423-
24242421
C.SectionsToScan.push_back(ConformanceSection{begin, end});
2425-
24262422
pthread_mutex_unlock(&C.SectionsToScanLock);
24272423
}
24282424

@@ -2437,7 +2433,10 @@ static void _addImageProtocolConformancesBlock(const uint8_t *conformances,
24372433
auto recordsEnd
24382434
= reinterpret_cast<const ProtocolConformanceRecord*>
24392435
(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);
24412440
}
24422441

24432442
#if defined(__APPLE__) && defined(__MACH__)
@@ -2490,26 +2489,32 @@ static int _addImageProtocolConformances(struct dl_phdr_info *info,
24902489
}
24912490
#endif
24922491

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);
25132518
}
25142519

25152520
static size_t hashTypeProtocolPair(const void *type,
@@ -2630,7 +2635,6 @@ swift::swift_conformsToProtocol(const Metadata *type,
26302635

26312636
// Install callbacks for tracking when a new dylib is loaded so we can
26322637
// scan it.
2633-
installCallbacksToInspectDylib();
26342638
auto origType = type;
26352639

26362640
unsigned numSections = 0;

0 commit comments

Comments
 (0)