Skip to content

Commit 1102e93

Browse files
authored
Merge pull request #59543 from mikeash/fix-shared-cache-conformance-short-circuit-5.7
[5.7][Runtime] Fix short-circuiting of shared cache conformance lookups.
2 parents ecb5231 + a9b573d commit 1102e93

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)