Skip to content

Commit f2407bf

Browse files
committed
[Runtime] Fix short-circuiting of shared cache conformance lookups.
We were skipping shared cache queries if the ObjC metadata or descriptor were outside the shared cache, but we need to skip only if they're both outside the shared cache. We also need to check foreign types even if the descriptor is outside the shared cache. rdar://93931813
1 parent 5781b14 commit f2407bf

File tree

1 file changed

+24
-13
lines changed

1 file changed

+24
-13
lines changed

stdlib/public/runtime/ProtocolConformance.cpp

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -802,27 +802,36 @@ static _dyld_protocol_conformance_result getDyldSharedCacheConformance(
802802
ConformanceState &C, const ProtocolDescriptor *protocol,
803803
const ClassMetadata *objcClassMetadata,
804804
const ContextDescriptor *description, llvm::StringRef foreignTypeIdentity) {
805-
// Protocols, classes, and descriptions that aren't in the shared cache will
806-
// never be found in the shared cache conformances. Foreign types are
807-
// non-unique so those can still be found in the shared cache regardless of
808-
// where the we got the identity.
809-
if (!C.inSharedCache(protocol) ||
810-
(objcClassMetadata && !C.inSharedCache(objcClassMetadata)) ||
811-
(description && !C.inSharedCache(description))) {
812-
DYLD_CONFORMANCES_LOG("Skipping shared cache lookup, protocol %p, class "
813-
"%p, or description %p is not in shared cache.",
814-
protocol, objcClassMetadata, description);
805+
// Protocols that aren't in the shared cache will never be found in the shared
806+
// cache conformances, skip the call.
807+
if (!C.inSharedCache(protocol)) {
808+
DYLD_CONFORMANCES_LOG(
809+
"Skipping shared cache lookup, protocol %p is not in shared cache.",
810+
protocol);
815811
return {_dyld_protocol_conformance_result_kind_not_found, nullptr};
816812
}
817813

818814
if (!foreignTypeIdentity.empty()) {
815+
// Foreign types are non-unique so those can still be found in the shared
816+
// cache even if the identity string is outside.
819817
DYLD_CONFORMANCES_LOG(
820818
"_dyld_find_foreign_type_protocol_conformance(%p, %.*s, %zu)", protocol,
821819
(int)foreignTypeIdentity.size(), foreignTypeIdentity.data(),
822820
foreignTypeIdentity.size());
823821
return _dyld_find_foreign_type_protocol_conformance(
824822
protocol, foreignTypeIdentity.data(), foreignTypeIdentity.size());
825823
} else {
824+
// If both the ObjC class metadata and description are outside the shared
825+
// cache, then we'll never find a shared cache conformance, skip the call.
826+
// We can still find a shared cache conformance if one is inside and one is
827+
// outside.
828+
if (!C.inSharedCache(objcClassMetadata) && !C.inSharedCache(description)) {
829+
DYLD_CONFORMANCES_LOG("Skipping shared cache lookup, class %p and "
830+
"description %p are not in shared cache.",
831+
objcClassMetadata, description);
832+
return {_dyld_protocol_conformance_result_kind_not_found, nullptr};
833+
}
834+
826835
DYLD_CONFORMANCES_LOG("_dyld_find_protocol_conformance(%p, %p, %p)",
827836
protocol, objcClassMetadata, description);
828837
return _dyld_find_protocol_conformance(protocol, objcClassMetadata,
@@ -876,9 +885,11 @@ findConformanceWithDyld(ConformanceState &C, const Metadata *type,
876885
auto objcClassMetadata = swift_getObjCClassFromMetadataConditional(type);
877886
#if SHARED_CACHE_LOG_ENABLED
878887
auto typeName = swift_getTypeName(type, true);
879-
DYLD_CONFORMANCES_LOG("Looking up conformance of %.*s to %s",
880-
(int)typeName.length, typeName.data,
881-
protocol->Name.get());
888+
DYLD_CONFORMANCES_LOG("Looking up conformance of %.*s (type=%p, "
889+
"objcClassMetadata=%p, description=%p) to %s (%p)",
890+
(int)typeName.length, typeName.data, type,
891+
objcClassMetadata, description, protocol->Name.get(),
892+
protocol);
882893
#endif
883894
_dyld_protocol_conformance_result dyldResult;
884895
if (C.scanSectionsBackwards) {

0 commit comments

Comments
 (0)