mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
When we generate code that asks for complete metadata for a fully concrete specific type that doesn't have trivial metadata access, like `(Int, String)` or `[String: [Any]]`, generate a cache variable that points to a mangled name, and use a common accessor function that turns that cache variable into a pointer to the instantiated metadata. This saves a bunch of code size, and should have minimal runtime impact, since the demangling of any string only has to happen once. This mostly just works, though it exposed a couple of issues: - Mangling a type ref including objc protocols didn't cause the objc protocol record to get instantiated. Fixed as part of this patch. - The runtime type demangler doesn't correctly handle retroactive conformances. If there are multiple retroactive conformances in a process at runtime, then even though the mangled string refers to a specific conformance, the runtime still just picks one without listening to the mangler. This is left to fix later, rdar://problem/53828345. There is some more follow-up work that we can do to further improve the gains: - We could improve the runtime-provided entry points, adding versions that don't require size to be cached, and which can handle arbitrary metadata requests. This would allow for mangled names to also be used for incomplete metadata accesses and improve code size of some generic type accessors. However, we'd only be able to take advantage of the new entry points in OSes that ship a new runtime. - We could choose to always symbolic reference all type references, which would generally reduce the size of mangled strings, as well as make runtime demangling more efficient, since it wouldn't need to hit the runtime caches. This would however require that we be able to handle symbolic references across files in the MetadataReader in order to avoid regressing remote mirror functionality.
71 lines
3.4 KiB
Swift
71 lines
3.4 KiB
Swift
// RUN: %empty-directory(%t)
|
|
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/weak_import_availability_helper.swiftmodule -parse-as-library %S/Inputs/weak_import_availability_helper.swift -enable-library-evolution
|
|
//
|
|
// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir | %FileCheck %s --check-prefix=CHECK-OLD
|
|
// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target x86_64-apple-macosx10.50 | %FileCheck %s --check-prefix=CHECK-NEW
|
|
// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target x86_64-apple-macosx10.60 | %FileCheck %s --check-prefix=CHECK-NEW
|
|
|
|
// REQUIRES: OS=macosx
|
|
// REQUIRES: CPU=x86_64
|
|
|
|
import weak_import_availability_helper
|
|
|
|
public func useConditionallyAvailableCase(e: AlwaysAvailableEnum) {
|
|
switch e {
|
|
case .alwaysAvailableCase: break
|
|
case .conditionallyAvailableCase: break
|
|
}
|
|
}
|
|
|
|
// CHECK-OLD-LABEL: @"$s31weak_import_availability_helper19AlwaysAvailableEnumO013conditionallyF4CaseyA2CmFWC" = extern_weak constant i32
|
|
// CHECK-NEW-LABEL: @"$s31weak_import_availability_helper19AlwaysAvailableEnumO013conditionallyF4CaseyA2CmFWC" = external constant i32
|
|
|
|
func useConformance<T : AlwaysAvailableProtocol>(_: T.Type) {}
|
|
|
|
@available(macOS 10.50, *)
|
|
public func useConditionallyAvailableConformance() {
|
|
useConformance(AlwaysAvailableStruct.self)
|
|
}
|
|
|
|
// FIXME: We reference the witness table directly -- that's a bug since the module is resilient. Should reference the
|
|
// conformance descriptor instead.
|
|
|
|
// CHECK-OLD-LABEL: @"$s31weak_import_availability_helper21AlwaysAvailableStructVAA0eF8ProtocolAAWP" = extern_weak global i8*
|
|
// CHECK-NEW-LABEL: @"$s31weak_import_availability_helper21AlwaysAvailableStructVAA0eF8ProtocolAAWP" = external global i8*
|
|
|
|
@available(macOS 10.50, *)
|
|
public func callConditionallyAvailableFunction() {
|
|
conditionallyAvailableFunction()
|
|
}
|
|
|
|
// CHECK-OLD-LABEL: declare extern_weak swiftcc void @"$s31weak_import_availability_helper30conditionallyAvailableFunctionyyF"()
|
|
// CHECK-NEW-LABEL: declare swiftcc void @"$s31weak_import_availability_helper30conditionallyAvailableFunctionyyF"()
|
|
|
|
@available(macOS 10.50, *)
|
|
public func useConditionallyAvailableGlobal() {
|
|
_ = conditionallyAvailableGlobal
|
|
conditionallyAvailableGlobal = 0
|
|
conditionallyAvailableGlobal += 1
|
|
}
|
|
|
|
// CHECK-OLD-LABEL: declare extern_weak swiftcc i64 @"$s31weak_import_availability_helper28conditionallyAvailableGlobalSivg"()
|
|
// CHECK-NEW-LABEL: declare swiftcc i64 @"$s31weak_import_availability_helper28conditionallyAvailableGlobalSivg"()
|
|
|
|
// CHECK-OLD-LABEL: declare extern_weak swiftcc void @"$s31weak_import_availability_helper28conditionallyAvailableGlobalSivs"(i64)
|
|
// CHECK-NEW-LABEL: declare swiftcc void @"$s31weak_import_availability_helper28conditionallyAvailableGlobalSivs"(i64)
|
|
|
|
func blackHole<T>(_: T) {}
|
|
|
|
@available(macOS 10.50, *)
|
|
public func useConditionallyAvailableStruct() {
|
|
blackHole(ConditionallyAvailableStruct.self)
|
|
}
|
|
|
|
@available(macOS 10.50, *)
|
|
public func useConditionallyAvailableMethod(s: ConditionallyAvailableStruct) {
|
|
s.conditionallyAvailableMethod()
|
|
}
|
|
|
|
// CHECK-OLD-LABEL: declare extern_weak swiftcc void @"$s31weak_import_availability_helper28ConditionallyAvailableStructV013conditionallyF6MethodyyF"(%swift.opaque* noalias nocapture swiftself)
|
|
// CHECK-NEW-LABEL: declare swiftcc void @"$s31weak_import_availability_helper28ConditionallyAvailableStructV013conditionallyF6MethodyyF"(%swift.opaque* noalias nocapture swiftself)
|