Skip to content

Commit de2a8b7

Browse files
authored
Merge pull request #31256 from jckarter/backport-conformance-cache-51
Compatibility51: Backport the 5.2 implementation of the conformance cache.
2 parents b297ea6 + ca48939 commit de2a8b7

File tree

11 files changed

+1211
-47
lines changed

11 files changed

+1211
-47
lines changed

include/swift/Runtime/Config.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,14 @@
154154
# elif SWIFT_BNI_XCODE_BUILD
155155
# define SWIFT_CLASS_IS_SWIFT_MASK 1ULL
156156

157+
// Compatibility hook libraries cannot rely on the "is swift" bit being either
158+
// value, since they must work with both OS and Xcode versions of the libraries.
159+
// Generate a reference to a nonexistent symbol so that we get obvious linker
160+
// errors if we try.
161+
# elif SWIFT_COMPATIBILITY_LIBRARY
162+
extern uintptr_t __COMPATIBILITY_LIBRARIES_CANNOT_CHECK_THE_IS_SWIFT_BIT_DIRECTLY__;
163+
# define SWIFT_CLASS_IS_SWIFT_MASK __COMPATIBILITY_LIBRARIES_CANNOT_CHECK_THE_IS_SWIFT_BIT_DIRECTLY__
164+
157165
// Other builds (such as local builds on developers' computers)
158166
// dynamically choose the bit at runtime based on the current OS
159167
// version.

stdlib/toolchain/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ else()
5656
add_compile_definitions(LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING=1)
5757
endif()
5858

59+
# Compatibility libraries build in a special alternate universe that can't
60+
# directly link to most OS runtime libraries, and have to access the
61+
# runtime being patched only through public ABI.
62+
list(APPEND CXX_COMPILE_FLAGS "-DSWIFT_COMPATIBILITY_LIBRARY=1")
5963

6064
add_subdirectory(legacy_layouts)
6165
add_subdirectory(Compatibility50)

stdlib/toolchain/Compatibility50/Overrides.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
//===----------------------------------------------------------------------===//
1616

1717
#include "Overrides.h"
18+
#include "../Compatibility51/Overrides.h"
1819
#include "../../public/runtime/CompatibilityOverride.h"
1920

2021
#include <dlfcn.h>
@@ -34,6 +35,11 @@ OverrideSection Swift50Overrides
3435
__attribute__((used, section("__DATA,__swift_hooks"))) = {
3536
.version = 0,
3637
.conformsToProtocol = swift50override_conformsToProtocol,
38+
// We use the same hook for conformsToSwiftProtocol as we do for a 5.1
39+
// runtime, so reference the override from the Compatibility51 library.
40+
// If we're back deploying to Swift 5.0, we also have to support 5.1, so
41+
// the Compatibility51 library is always linked when the 50 library is.
42+
.conformsToSwiftProtocol = swift51override_conformsToSwiftProtocol,
3743
};
3844

3945
// Allow this library to get force-loaded by autolinking

stdlib/toolchain/Compatibility50/Overrides.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
//===--- Overrides.cpp - Compat overrides for Swift 5.0 runtime ----s------===//
1+
//===--- Overrides.h --- Compat overrides for Swift 5.0 runtime ----s------===//
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information

stdlib/toolchain/Compatibility50/ProtocolConformance.cpp

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,6 @@ using mach_header_platform = mach_header;
3737
/// This lives within SEG_TEXT.
3838
constexpr const char ProtocolConformancesSection[] = "__swift5_proto";
3939

40-
// Clone of private function getRootSuperclass. This returns the SwiftObject
41-
// class in the ABI-stable dylib, regardless of what the local runtime build
42-
// does, since we're always patching an ABI-stable dylib.
43-
__attribute__((visibility("hidden"), weak))
44-
const ClassMetadata *swift::getRootSuperclass() {
45-
auto theClass = SWIFT_LAZY_CONSTANT(objc_getClass("_TtCs12_SwiftObject"));
46-
return (const ClassMetadata *)theClass;
47-
}
48-
4940
// A dummy target context descriptor to use in conformance records which point
5041
// to a NULL descriptor. It doesn't have to be completely valid, just something
5142
// that code reading conformance descriptors will ignore.
@@ -90,35 +81,9 @@ static void registerAddImageCallback(void *) {
9081
_dyld_register_func_for_add_image(addImageCallback);
9182
}
9283

93-
static const Metadata *getObjCClassMetadata(const ClassMetadata *c) {
94-
// Look up swift_getObjCClassMetadata dynamically. This handles the case
95-
// where the main executable can't link against libswiftCore.dylib because
96-
// it will be loaded dynamically from a location that isn't known at build
97-
// time.
98-
using FPtr = const Metadata *(*)(const ClassMetadata *);
99-
FPtr func = SWIFT_LAZY_CONSTANT(
100-
reinterpret_cast<FPtr>(dlsym(RTLD_DEFAULT, "swift_getObjCClassMetadata")));
101-
102-
return func(c);
103-
}
104-
105-
// Clone of private helper swift::_swiftoverride_class_getSuperclass
106-
// for use in the override implementation.
107-
static const Metadata *_swift50override_class_getSuperclass(
108-
const Metadata *theClass) {
109-
if (const ClassMetadata *classType = theClass->getClassObject()) {
110-
if (classHasSuperclass(classType))
111-
return getObjCClassMetadata(classType->Superclass);
112-
}
113-
114-
if (const ForeignClassMetadata *foreignClassType
115-
= dyn_cast<ForeignClassMetadata>(theClass)) {
116-
if (const Metadata *superclass = foreignClassType->Superclass)
117-
return superclass;
118-
}
119-
120-
return nullptr;
121-
}
84+
// Defined in libswiftCompatibility51, which is always linked if we link against
85+
// libswiftCompatibility50
86+
const Metadata *_swiftoverride_class_getSuperclass(const Metadata *theClass);
12287

12388
const WitnessTable *
12489
swift::swift50override_conformsToProtocol(const Metadata *type,
@@ -138,7 +103,7 @@ swift::swift50override_conformsToProtocol(const Metadata *type,
138103
auto result = original_conformsToProtocol(type, protocol);
139104
if (result)
140105
return result;
141-
} while ((type = _swift50override_class_getSuperclass(type)));
106+
} while ((type = _swiftoverride_class_getSuperclass(type)));
142107

143108
return nullptr;
144109
}

stdlib/toolchain/Compatibility51/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ set(library_name "swiftCompatibility51")
33

44
add_swift_target_library("${library_name}" STATIC
55
Overrides.cpp
6+
ProtocolConformance.cpp
67

78
TARGET_SDKS ${SWIFT_APPLE_PLATFORMS}
89

0 commit comments

Comments
 (0)