mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This change adds a new type of cache (cache by type descriptor) to the protocol conformance lookup system. This optimization is beneficial for generic types, where the same conformance can be reused across different instantiations of the generic type. Key changes: - Add a `GetOrInsertManyScope` class to `ConcurrentReadableHashMap` for performing multiple insertions under a single lock - Add type descriptor-based caching for protocol conformances - Add environment variables for controlling and debugging the conformance cache - Add tests to verify the behavior of the conformance cache - Fix for https://github.com/swiftlang/swift/issues/82889 The implementation is controlled by the `SWIFT_DEBUG_ENABLE_CACHE_PROTOCOL_CONFORMANCES_BY_TYPE_DESCRIPTOR` environment variable, which is enabled by default. This reapplies https://github.com/swiftlang/swift/pull/82818 after it's been reverted in https://github.com/swiftlang/swift/pull/83770.
52 lines
1.8 KiB
Swift
52 lines
1.8 KiB
Swift
// RUN: %empty-directory(%t)
|
|
// RUN: %target-build-swift %s -o %t/a.out
|
|
// RUN: env SWIFT_DEBUG_ENABLE_PROTOCOL_CONFORMANCES_LOOKUP_LOG=1 %target-run %t/a.out 2>&1 | %FileCheck %s
|
|
|
|
// REQUIRES: executable_test
|
|
// REQUIRES: objc_interop
|
|
// REQUIRES: swift_stdlib_asserts
|
|
// UNSUPPORTED: DARWIN_SIMULATOR=ios
|
|
// UNSUPPORTED: DARWIN_SIMULATOR=tvos
|
|
// UNSUPPORTED: DARWIN_SIMULATOR=watchos
|
|
// UNSUPPORTED: DARWIN_SIMULATOR=xros
|
|
// UNSUPPORTED: use_os_stdlib
|
|
|
|
// The optimizer will remove many of these conformance checks due to statically
|
|
// knowing the result.
|
|
// UNSUPPORTED: swift_test_mode_optimize
|
|
// UNSUPPORTED: swift_test_mode_optimize_size
|
|
|
|
import Foundation
|
|
|
|
protocol Proto {}
|
|
extension Proto {
|
|
static var selfType: Any.Type { Self.self }
|
|
}
|
|
|
|
func conformsToProto<T>(_ type: T.Type) -> Bool {
|
|
(type as? Proto.Type)?.selfType == type
|
|
}
|
|
|
|
func doesNotConformToProto<T>(_ type: T) -> Bool {
|
|
(type as? Proto.Type) == nil
|
|
}
|
|
|
|
@objc class BaseClass: NSObject, Proto {}
|
|
@objc class DerivedClass: BaseClass {}
|
|
@objc class NonConformingClass: NSObject {}
|
|
|
|
// CHECK: Check confomance a.BaseClass to Proto: found, source: section scan
|
|
assert(conformsToProto(BaseClass.self))
|
|
// CHECK: Check confomance a.BaseClass to Proto: found, source: cache by type metadata
|
|
assert(conformsToProto(BaseClass.self))
|
|
|
|
// CHECK: Check confomance a.DerivedClass to Proto: found, source: section scan
|
|
assert(conformsToProto(DerivedClass.self))
|
|
// CHECK: Check confomance a.DerivedClass to Proto: found, source: cache by type metadata
|
|
assert(conformsToProto(DerivedClass.self))
|
|
|
|
// CHECK: Check confomance a.NonConformingClass to Proto: not found, source: section scan
|
|
assert(doesNotConformToProto(NonConformingClass.self))
|
|
// CHECK: Check confomance a.NonConformingClass to Proto: not found, source: cache by type metadata
|
|
assert(doesNotConformToProto(NonConformingClass.self))
|