Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 24 additions & 13 deletions stdlib/public/runtime/ProtocolConformance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -802,27 +802,36 @@ static _dyld_protocol_conformance_result getDyldSharedCacheConformance(
ConformanceState &C, const ProtocolDescriptor *protocol,
const ClassMetadata *objcClassMetadata,
const ContextDescriptor *description, llvm::StringRef foreignTypeIdentity) {
// Protocols, classes, and descriptions that aren't in the shared cache will
// never be found in the shared cache conformances. Foreign types are
// non-unique so those can still be found in the shared cache regardless of
// where the we got the identity.
if (!C.inSharedCache(protocol) ||
(objcClassMetadata && !C.inSharedCache(objcClassMetadata)) ||
(description && !C.inSharedCache(description))) {
DYLD_CONFORMANCES_LOG("Skipping shared cache lookup, protocol %p, class "
"%p, or description %p is not in shared cache.",
protocol, objcClassMetadata, description);
// Protocols that aren't in the shared cache will never be found in the shared
// cache conformances, skip the call.
if (!C.inSharedCache(protocol)) {
DYLD_CONFORMANCES_LOG(
"Skipping shared cache lookup, protocol %p is not in shared cache.",
protocol);
return {_dyld_protocol_conformance_result_kind_not_found, nullptr};
}

if (!foreignTypeIdentity.empty()) {
// Foreign types are non-unique so those can still be found in the shared
// cache even if the identity string is outside.
DYLD_CONFORMANCES_LOG(
"_dyld_find_foreign_type_protocol_conformance(%p, %.*s, %zu)", protocol,
(int)foreignTypeIdentity.size(), foreignTypeIdentity.data(),
foreignTypeIdentity.size());
return _dyld_find_foreign_type_protocol_conformance(
protocol, foreignTypeIdentity.data(), foreignTypeIdentity.size());
} else {
// If both the ObjC class metadata and description are outside the shared
// cache, then we'll never find a shared cache conformance, skip the call.
// We can still find a shared cache conformance if one is inside and one is
// outside.
if (!C.inSharedCache(objcClassMetadata) && !C.inSharedCache(description)) {
DYLD_CONFORMANCES_LOG("Skipping shared cache lookup, class %p and "
"description %p are not in shared cache.",
objcClassMetadata, description);
return {_dyld_protocol_conformance_result_kind_not_found, nullptr};
}

DYLD_CONFORMANCES_LOG("_dyld_find_protocol_conformance(%p, %p, %p)",
protocol, objcClassMetadata, description);
return _dyld_find_protocol_conformance(protocol, objcClassMetadata,
Expand Down Expand Up @@ -876,9 +885,11 @@ findConformanceWithDyld(ConformanceState &C, const Metadata *type,
auto objcClassMetadata = swift_getObjCClassFromMetadataConditional(type);
#if SHARED_CACHE_LOG_ENABLED
auto typeName = swift_getTypeName(type, true);
DYLD_CONFORMANCES_LOG("Looking up conformance of %.*s to %s",
(int)typeName.length, typeName.data,
protocol->Name.get());
DYLD_CONFORMANCES_LOG("Looking up conformance of %.*s (type=%p, "
"objcClassMetadata=%p, description=%p) to %s (%p)",
(int)typeName.length, typeName.data, type,
objcClassMetadata, description, protocol->Name.get(),
protocol);
#endif
_dyld_protocol_conformance_result dyldResult;
if (C.scanSectionsBackwards) {
Expand Down