Skip to content

Commit 110f2fc

Browse files
committed
Backward deployment shim for swift_allocate{Metadata,WitnessTable}Pack()
1 parent b116d35 commit 110f2fc

File tree

9 files changed

+255
-29
lines changed

9 files changed

+255
-29
lines changed

include/swift/Frontend/BackDeploymentLibs.def

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@
2121
//===----------------------------------------------------------------------===//
2222

2323
#ifndef BACK_DEPLOYMENT_LIB
24-
# error "Must define BACK_DEPLOYMENT_LIB(Version, Filter, Library)"
24+
# error "Must define BACK_DEPLOYMENT_LIB(Version, Filter, Library, ForceLoad)"
2525
#endif
2626

27-
BACK_DEPLOYMENT_LIB((5, 0), all, "swiftCompatibility50")
28-
BACK_DEPLOYMENT_LIB((5, 1), all, "swiftCompatibility51")
29-
BACK_DEPLOYMENT_LIB((5, 0), executable, "swiftCompatibilityDynamicReplacements")
30-
BACK_DEPLOYMENT_LIB((5, 4), all, "swiftCompatibilityConcurrency")
31-
BACK_DEPLOYMENT_LIB((5, 6), all, "swiftCompatibility56")
27+
BACK_DEPLOYMENT_LIB((5, 0), all, "swiftCompatibility50", true)
28+
BACK_DEPLOYMENT_LIB((5, 1), all, "swiftCompatibility51", true)
29+
BACK_DEPLOYMENT_LIB((5, 0), executable, "swiftCompatibilityDynamicReplacements", true)
30+
BACK_DEPLOYMENT_LIB((5, 4), all, "swiftCompatibilityConcurrency", true)
31+
BACK_DEPLOYMENT_LIB((5, 6), all, "swiftCompatibility56", true)
32+
BACK_DEPLOYMENT_LIB((5, 8), all, "swiftCompatibilityPacks", false)
3233

3334
#undef BACK_DEPLOYMENT_LIB

lib/Basic/TargetInfo.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ using namespace swift;
2323
/// Print information about a
2424
static void printCompatibilityLibrary(
2525
llvm::VersionTuple runtimeVersion, llvm::VersionTuple maxVersion,
26-
StringRef filter, StringRef libraryName, bool &printedAny,
27-
llvm::raw_ostream &out) {
26+
StringRef filter, StringRef libraryName, bool forceLoad,
27+
bool &printedAny, llvm::raw_ostream &out) {
2828
if (runtimeVersion > maxVersion)
2929
return;
3030

@@ -33,16 +33,21 @@ static void printCompatibilityLibrary(
3333
}
3434

3535
out << "\n";
36-
out << " {\n";
36+
out << " {";
3737

38-
out << " \"libraryName\": \"";
38+
out << "\n \"libraryName\": \"";
3939
swift::writeEscaped(libraryName, out);
40-
out << "\",\n";
40+
out << "\",";
4141

42-
out << " \"filter\": \"";
42+
out << "\n \"filter\": \"";
4343
swift::writeEscaped(filter, out);
44-
out << "\"\n";
45-
out << " }";
44+
out << "\"";
45+
46+
if (!forceLoad) {
47+
out << ",\n \"forceLoad\": false";
48+
}
49+
50+
out << "\n }";
4651

4752
printedAny = true;
4853
}
@@ -132,10 +137,10 @@ void targetinfo::printTripleInfo(const llvm::Triple &triple,
132137
// Compatibility libraries that need to be linked.
133138
out << " \"compatibilityLibraries\": [";
134139
bool printedAnyCompatibilityLibrary = false;
135-
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName) \
136-
printCompatibilityLibrary( \
140+
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName, ForceLoad) \
141+
printCompatibilityLibrary( \
137142
*runtimeVersion, llvm::VersionTuple Version, #Filter, LibraryName, \
138-
printedAnyCompatibilityLibrary, out);
143+
ForceLoad, printedAnyCompatibilityLibrary, out);
139144
#include "swift/Frontend/BackDeploymentLibs.def"
140145

141146
if (printedAnyCompatibilityLibrary) {

lib/Driver/DarwinToolChains.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,8 @@ toolchains::Darwin::addArgsToLinkStdlib(ArgStringList &Arguments,
406406
runtimeCompatibilityVersion = llvm::VersionTuple(5, 5);
407407
} else if (value.equals("5.6")) {
408408
runtimeCompatibilityVersion = llvm::VersionTuple(5, 6);
409+
} else if (value.equals("5.8")) {
410+
runtimeCompatibilityVersion = llvm::VersionTuple(5, 8);
409411
} else if (value.equals("none")) {
410412
runtimeCompatibilityVersion = None;
411413
} else {
@@ -419,7 +421,8 @@ toolchains::Darwin::addArgsToLinkStdlib(ArgStringList &Arguments,
419421
if (runtimeCompatibilityVersion) {
420422
auto addBackDeployLib = [&](llvm::VersionTuple version,
421423
BackDeployLibFilter filter,
422-
StringRef libraryName) {
424+
StringRef libraryName,
425+
bool forceLoad) {
423426
if (*runtimeCompatibilityVersion > version)
424427
return;
425428

@@ -431,14 +434,16 @@ toolchains::Darwin::addArgsToLinkStdlib(ArgStringList &Arguments,
431434
llvm::sys::path::append(BackDeployLib, "lib" + libraryName + ".a");
432435

433436
if (llvm::sys::fs::exists(BackDeployLib)) {
434-
Arguments.push_back("-force_load");
437+
if (forceLoad)
438+
Arguments.push_back("-force_load");
435439
Arguments.push_back(context.Args.MakeArgString(BackDeployLib));
436440
}
437441
};
438442

439-
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName) \
440-
addBackDeployLib( \
441-
llvm::VersionTuple Version, BackDeployLibFilter::Filter, LibraryName);
443+
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName, ForceLoad) \
444+
addBackDeployLib( \
445+
llvm::VersionTuple Version, BackDeployLibFilter::Filter, \
446+
LibraryName, ForceLoad);
442447
#include "swift/Frontend/BackDeploymentLibs.def"
443448
}
444449

lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2607,6 +2607,8 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
26072607
runtimeCompatibilityVersion = llvm::VersionTuple(5, 5);
26082608
} else if (version.equals("5.6")) {
26092609
runtimeCompatibilityVersion = llvm::VersionTuple(5, 6);
2610+
} else if (version.equals("5.8")) {
2611+
runtimeCompatibilityVersion = llvm::VersionTuple(5, 8);
26102612
} else {
26112613
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
26122614
versionArg->getAsString(Args), version);

lib/IRGen/GenDecl.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,8 @@ void IRGenModule::emitSourceFile(SourceFile &SF) {
511511
// harmless aside from code size.
512512
if (!IRGen.Opts.UseJIT) {
513513
auto addBackDeployLib = [&](llvm::VersionTuple version,
514-
StringRef libraryName) {
514+
StringRef libraryName,
515+
bool forceLoad) {
515516
Optional<llvm::VersionTuple> compatibilityVersion;
516517
if (libraryName == "swiftCompatibilityDynamicReplacements") {
517518
compatibilityVersion = IRGen.Opts.
@@ -532,11 +533,11 @@ void IRGenModule::emitSourceFile(SourceFile &SF) {
532533

533534
this->addLinkLibrary(LinkLibrary(libraryName,
534535
LibraryKind::Library,
535-
/*forceLoad*/ true));
536+
forceLoad));
536537
};
537538

538-
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName) \
539-
addBackDeployLib(llvm::VersionTuple Version, LibraryName);
539+
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName, ForceLoad) \
540+
addBackDeployLib(llvm::VersionTuple Version, LibraryName, ForceLoad);
540541
#include "swift/Frontend/BackDeploymentLibs.def"
541542
}
542543
}

stdlib/toolchain/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ if(SWIFT_STDLIB_SUPPORT_BACK_DEPLOYMENT)
5454
add_subdirectory(CompatibilityDynamicReplacements)
5555
add_subdirectory(CompatibilityConcurrency)
5656
add_subdirectory(CompatibilityThreading)
57+
add_subdirectory(CompatibilityPacks)
5758

5859
# This is a convenience target to have the list
5960
# of all the compatibility libraries needed to build
@@ -63,6 +64,7 @@ if(SWIFT_STDLIB_SUPPORT_BACK_DEPLOYMENT)
6364
target_link_libraries(HostCompatibilityLibs INTERFACE
6465
swiftCompatibilityConcurrency${vsuffix}
6566
swiftCompatibilityDynamicReplacements${vsuffix}
67+
swiftCompatibilityPacks${vsuffix}
6668
swiftCompatibility50${vsuffix}
6769
swiftCompatibility51${vsuffix}
6870
swiftCompatibility56${vsuffix})
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
set(library_name "swiftCompatibilityPacks")
2+
3+
include_directories("include/" "${SWIFT_STDLIB_SOURCE_DIR}")
4+
5+
set(CMAKE_C_VISIBILITY_PRESET hidden)
6+
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
7+
set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)
8+
9+
add_compile_definitions(SWIFT_COMPATIBILITY_PACKS)
10+
add_swift_target_library("${library_name}" STATIC
11+
Metadata.cpp
12+
13+
TARGET_SDKS ${SWIFT_DARWIN_PLATFORMS}
14+
15+
C_COMPILE_FLAGS
16+
${CXX_COMPILE_FLAGS}
17+
"-D__STDC_WANT_LIB_EXT1__=1"
18+
LINK_FLAGS ${CXX_LINK_FLAGS}
19+
INCORPORATE_OBJECT_LIBRARIES swiftCompatibilityThreading
20+
SWIFT_COMPILE_FLAGS ${SWIFT_STANDARD_LIBRARY_SWIFT_FLAGS}
21+
DEPLOYMENT_VERSION_OSX ${COMPATIBILITY_MINIMUM_DEPLOYMENT_VERSION_OSX}
22+
DEPLOYMENT_VERSION_IOS ${COMPATIBILITY_MINIMUM_DEPLOYMENT_VERSION_IOS}
23+
DEPLOYMENT_VERSION_TVOS ${COMPATIBILITY_MINIMUM_DEPLOYMENT_VERSION_TVOS}
24+
DEPLOYMENT_VERSION_WATCHOS ${COMPATIBILITY_MINIMUM_DEPLOYMENT_VERSION_WATCHOS}
25+
26+
MACCATALYST_BUILD_FLAVOR "zippered"
27+
28+
INSTALL_IN_COMPONENT compiler
29+
INSTALL_WITH_SHARED)
30+
31+
32+
# FIXME: We need a more flexible mechanism to add lipo targets generated by
33+
# add_swift_target_library to the ALL target. Until then this hack is necessary
34+
# to ensure these libraries build.
35+
foreach(sdk ${SWIFT_SDKS})
36+
set(target_name "${library_name}-${SWIFT_SDK_${sdk}_LIB_SUBDIR}")
37+
if(NOT TARGET "${target_name}")
38+
continue()
39+
endif()
40+
41+
set_target_properties("${target_name}"
42+
PROPERTIES
43+
EXCLUDE_FROM_ALL FALSE)
44+
endforeach()
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
//===--- Metadata.cpp -----------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// Backward deployment of swift_allocateMetadataPack() and
14+
// swift_allocateWitnessTablePack() runtime entry points.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#include "../../public/runtime/MetadataCache.h"
19+
20+
// Allow this library to get force-loaded by autolinking
21+
__attribute__((weak, visibility("hidden")))
22+
extern "C"
23+
char _swift_FORCE_LOAD_$_swiftCompatibilityPacks = 0;
24+
25+
using namespace swift;
26+
27+
/// Copy and paste some symbols that need to exist.
28+
void *MetadataAllocator::Allocate(size_t size, size_t alignment) {
29+
return malloc(size);
30+
}
31+
32+
/// Avoid depending on non-inline parts of llvm::hashing.
33+
inline llvm::hash_code our_hash_integer_value(uint64_t value) {
34+
const char *s = reinterpret_cast<const char *>(&value);
35+
const uint64_t a = llvm::hashing::detail::fetch32(s);
36+
return llvm::hashing::detail::hash_16_bytes(
37+
(a << 3), llvm::hashing::detail::fetch32(s + 4));
38+
}
39+
40+
static inline llvm::hash_code our_hash_combine(llvm::hash_code seed, llvm::hash_code v) {
41+
return seed ^ (v + 0x9e3779b9 + (seed<<6) + (seed>>2));
42+
}
43+
44+
/// Copy and paste from Metadata.cpp.
45+
46+
namespace {
47+
48+
template<typename PackType>
49+
class PackCacheEntry {
50+
public:
51+
size_t Count;
52+
53+
const PackType * const * getElements() const {
54+
return reinterpret_cast<const PackType * const *>(this + 1);
55+
}
56+
57+
const PackType ** getElements() {
58+
return reinterpret_cast<const PackType **>(this + 1);
59+
}
60+
61+
struct Key {
62+
const PackType *const *Data;
63+
const size_t Count;
64+
65+
size_t getCount() const {
66+
return Count;
67+
}
68+
69+
const PackType *getElement(size_t index) const {
70+
assert(index < Count);
71+
return Data[index];
72+
}
73+
74+
friend llvm::hash_code hash_value(const Key &key) {
75+
llvm::hash_code hash = 0;
76+
for (size_t i = 0; i != key.getCount(); ++i) {
77+
hash = our_hash_combine(hash, our_hash_integer_value(
78+
reinterpret_cast<uint64_t>(key.getElement(i))));
79+
}
80+
return hash;
81+
}
82+
};
83+
84+
PackCacheEntry(const Key &key);
85+
86+
intptr_t getKeyIntValueForDump() {
87+
return 0; // No single meaningful value here.
88+
}
89+
90+
bool matchesKey(const Key &key) const {
91+
if (key.getCount() != Count)
92+
return false;
93+
for (unsigned i = 0; i != Count; ++i) {
94+
if (key.getElement(i) != getElements()[i])
95+
return false;
96+
}
97+
return true;
98+
}
99+
100+
friend llvm::hash_code hash_value(const PackCacheEntry<PackType> &value) {
101+
llvm::hash_code hash = 0;
102+
for (size_t i = 0; i != value.Count; ++i) {
103+
hash = our_hash_combine(hash, our_hash_integer_value(
104+
reinterpret_cast<uint64_t>(value.getElements()[i])));
105+
}
106+
return hash;
107+
}
108+
109+
static size_t getExtraAllocationSize(const Key &key) {
110+
return getExtraAllocationSize(key.Count);
111+
}
112+
113+
size_t getExtraAllocationSize() const {
114+
return getExtraAllocationSize(Count);
115+
}
116+
117+
static size_t getExtraAllocationSize(unsigned count) {
118+
return count * sizeof(const Metadata * const *);
119+
}
120+
};
121+
122+
template<typename PackType>
123+
PackCacheEntry<PackType>::PackCacheEntry(
124+
const typename PackCacheEntry<PackType>::Key &key) {
125+
Count = key.getCount();
126+
127+
for (unsigned i = 0; i < Count; ++i)
128+
getElements()[i] = key.getElement(i);
129+
}
130+
131+
} // end anonymous namespace
132+
133+
/// The uniquing structure for metadata packs.
134+
static SimpleGlobalCache<PackCacheEntry<Metadata>,
135+
MetadataPackTag> MetadataPacks;
136+
137+
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
138+
const Metadata * const *
139+
swift_allocateMetadataPack(const Metadata * const *ptr, size_t count) {
140+
if (MetadataPackPointer(reinterpret_cast<uintptr_t>(ptr)).getLifetime()
141+
== PackLifetime::OnHeap)
142+
return ptr;
143+
144+
PackCacheEntry<Metadata>::Key key{ptr, count};
145+
auto bytes = MetadataPacks.getOrInsert(key).first->getElements();
146+
147+
MetadataPackPointer pack(bytes, PackLifetime::OnHeap);
148+
assert(pack.getNumElements() == count);
149+
return pack.getPointer();
150+
}
151+
152+
/// The uniquing structure for witness table packs.
153+
static SimpleGlobalCache<PackCacheEntry<WitnessTable>,
154+
WitnessTablePackTag> WitnessTablePacks;
155+
156+
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
157+
const WitnessTable * const *
158+
swift_allocateWitnessTablePack(const WitnessTable * const *ptr, size_t count) {
159+
if (WitnessTablePackPointer(reinterpret_cast<uintptr_t>(ptr)).getLifetime()
160+
== PackLifetime::OnHeap)
161+
return ptr;
162+
163+
PackCacheEntry<WitnessTable>::Key key{ptr, count};
164+
auto bytes = WitnessTablePacks.getOrInsert(key).first->getElements();
165+
166+
WitnessTablePackPointer pack(bytes, PackLifetime::OnHeap);
167+
assert(pack.getNumElements() == count);
168+
return pack.getPointer();
169+
}

test/Interpreter/variadic_generic_captures.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33

44
// REQUIRES: executable_test
55

6-
// UNSUPPORTED: use_os_stdlib
7-
// UNSUPPORTED: back_deployment_runtime
8-
96
import StdlibUnittest
107

118
var types = TestSuite("VariadicGenericCaptures")

0 commit comments

Comments
 (0)