mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Backward deployment shim for swift_allocate{Metadata,WitnessTable}Pack()
This commit is contained in:
@@ -21,13 +21,14 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef BACK_DEPLOYMENT_LIB
|
||||
# error "Must define BACK_DEPLOYMENT_LIB(Version, Filter, Library)"
|
||||
# error "Must define BACK_DEPLOYMENT_LIB(Version, Filter, Library, ForceLoad)"
|
||||
#endif
|
||||
|
||||
BACK_DEPLOYMENT_LIB((5, 0), all, "swiftCompatibility50")
|
||||
BACK_DEPLOYMENT_LIB((5, 1), all, "swiftCompatibility51")
|
||||
BACK_DEPLOYMENT_LIB((5, 0), executable, "swiftCompatibilityDynamicReplacements")
|
||||
BACK_DEPLOYMENT_LIB((5, 4), all, "swiftCompatibilityConcurrency")
|
||||
BACK_DEPLOYMENT_LIB((5, 6), all, "swiftCompatibility56")
|
||||
BACK_DEPLOYMENT_LIB((5, 0), all, "swiftCompatibility50", true)
|
||||
BACK_DEPLOYMENT_LIB((5, 1), all, "swiftCompatibility51", true)
|
||||
BACK_DEPLOYMENT_LIB((5, 0), executable, "swiftCompatibilityDynamicReplacements", true)
|
||||
BACK_DEPLOYMENT_LIB((5, 4), all, "swiftCompatibilityConcurrency", true)
|
||||
BACK_DEPLOYMENT_LIB((5, 6), all, "swiftCompatibility56", true)
|
||||
BACK_DEPLOYMENT_LIB((5, 8), all, "swiftCompatibilityPacks", false)
|
||||
|
||||
#undef BACK_DEPLOYMENT_LIB
|
||||
|
||||
@@ -23,8 +23,8 @@ using namespace swift;
|
||||
/// Print information about a
|
||||
static void printCompatibilityLibrary(
|
||||
llvm::VersionTuple runtimeVersion, llvm::VersionTuple maxVersion,
|
||||
StringRef filter, StringRef libraryName, bool &printedAny,
|
||||
llvm::raw_ostream &out) {
|
||||
StringRef filter, StringRef libraryName, bool forceLoad,
|
||||
bool &printedAny, llvm::raw_ostream &out) {
|
||||
if (runtimeVersion > maxVersion)
|
||||
return;
|
||||
|
||||
@@ -33,16 +33,21 @@ static void printCompatibilityLibrary(
|
||||
}
|
||||
|
||||
out << "\n";
|
||||
out << " {\n";
|
||||
out << " {";
|
||||
|
||||
out << " \"libraryName\": \"";
|
||||
out << "\n \"libraryName\": \"";
|
||||
swift::writeEscaped(libraryName, out);
|
||||
out << "\",\n";
|
||||
out << "\",";
|
||||
|
||||
out << " \"filter\": \"";
|
||||
out << "\n \"filter\": \"";
|
||||
swift::writeEscaped(filter, out);
|
||||
out << "\"\n";
|
||||
out << " }";
|
||||
out << "\"";
|
||||
|
||||
if (!forceLoad) {
|
||||
out << ",\n \"forceLoad\": false";
|
||||
}
|
||||
|
||||
out << "\n }";
|
||||
|
||||
printedAny = true;
|
||||
}
|
||||
@@ -132,10 +137,10 @@ void targetinfo::printTripleInfo(const llvm::Triple &triple,
|
||||
// Compatibility libraries that need to be linked.
|
||||
out << " \"compatibilityLibraries\": [";
|
||||
bool printedAnyCompatibilityLibrary = false;
|
||||
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName) \
|
||||
printCompatibilityLibrary( \
|
||||
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName, ForceLoad) \
|
||||
printCompatibilityLibrary( \
|
||||
*runtimeVersion, llvm::VersionTuple Version, #Filter, LibraryName, \
|
||||
printedAnyCompatibilityLibrary, out);
|
||||
ForceLoad, printedAnyCompatibilityLibrary, out);
|
||||
#include "swift/Frontend/BackDeploymentLibs.def"
|
||||
|
||||
if (printedAnyCompatibilityLibrary) {
|
||||
|
||||
@@ -406,6 +406,8 @@ toolchains::Darwin::addArgsToLinkStdlib(ArgStringList &Arguments,
|
||||
runtimeCompatibilityVersion = llvm::VersionTuple(5, 5);
|
||||
} else if (value.equals("5.6")) {
|
||||
runtimeCompatibilityVersion = llvm::VersionTuple(5, 6);
|
||||
} else if (value.equals("5.8")) {
|
||||
runtimeCompatibilityVersion = llvm::VersionTuple(5, 8);
|
||||
} else if (value.equals("none")) {
|
||||
runtimeCompatibilityVersion = None;
|
||||
} else {
|
||||
@@ -419,7 +421,8 @@ toolchains::Darwin::addArgsToLinkStdlib(ArgStringList &Arguments,
|
||||
if (runtimeCompatibilityVersion) {
|
||||
auto addBackDeployLib = [&](llvm::VersionTuple version,
|
||||
BackDeployLibFilter filter,
|
||||
StringRef libraryName) {
|
||||
StringRef libraryName,
|
||||
bool forceLoad) {
|
||||
if (*runtimeCompatibilityVersion > version)
|
||||
return;
|
||||
|
||||
@@ -431,14 +434,16 @@ toolchains::Darwin::addArgsToLinkStdlib(ArgStringList &Arguments,
|
||||
llvm::sys::path::append(BackDeployLib, "lib" + libraryName + ".a");
|
||||
|
||||
if (llvm::sys::fs::exists(BackDeployLib)) {
|
||||
Arguments.push_back("-force_load");
|
||||
if (forceLoad)
|
||||
Arguments.push_back("-force_load");
|
||||
Arguments.push_back(context.Args.MakeArgString(BackDeployLib));
|
||||
}
|
||||
};
|
||||
|
||||
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName) \
|
||||
addBackDeployLib( \
|
||||
llvm::VersionTuple Version, BackDeployLibFilter::Filter, LibraryName);
|
||||
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName, ForceLoad) \
|
||||
addBackDeployLib( \
|
||||
llvm::VersionTuple Version, BackDeployLibFilter::Filter, \
|
||||
LibraryName, ForceLoad);
|
||||
#include "swift/Frontend/BackDeploymentLibs.def"
|
||||
}
|
||||
|
||||
|
||||
@@ -2607,6 +2607,8 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
|
||||
runtimeCompatibilityVersion = llvm::VersionTuple(5, 5);
|
||||
} else if (version.equals("5.6")) {
|
||||
runtimeCompatibilityVersion = llvm::VersionTuple(5, 6);
|
||||
} else if (version.equals("5.8")) {
|
||||
runtimeCompatibilityVersion = llvm::VersionTuple(5, 8);
|
||||
} else {
|
||||
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
|
||||
versionArg->getAsString(Args), version);
|
||||
|
||||
@@ -511,7 +511,8 @@ void IRGenModule::emitSourceFile(SourceFile &SF) {
|
||||
// harmless aside from code size.
|
||||
if (!IRGen.Opts.UseJIT) {
|
||||
auto addBackDeployLib = [&](llvm::VersionTuple version,
|
||||
StringRef libraryName) {
|
||||
StringRef libraryName,
|
||||
bool forceLoad) {
|
||||
Optional<llvm::VersionTuple> compatibilityVersion;
|
||||
if (libraryName == "swiftCompatibilityDynamicReplacements") {
|
||||
compatibilityVersion = IRGen.Opts.
|
||||
@@ -532,11 +533,11 @@ void IRGenModule::emitSourceFile(SourceFile &SF) {
|
||||
|
||||
this->addLinkLibrary(LinkLibrary(libraryName,
|
||||
LibraryKind::Library,
|
||||
/*forceLoad*/ true));
|
||||
forceLoad));
|
||||
};
|
||||
|
||||
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName) \
|
||||
addBackDeployLib(llvm::VersionTuple Version, LibraryName);
|
||||
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName, ForceLoad) \
|
||||
addBackDeployLib(llvm::VersionTuple Version, LibraryName, ForceLoad);
|
||||
#include "swift/Frontend/BackDeploymentLibs.def"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ if(SWIFT_STDLIB_SUPPORT_BACK_DEPLOYMENT)
|
||||
add_subdirectory(CompatibilityDynamicReplacements)
|
||||
add_subdirectory(CompatibilityConcurrency)
|
||||
add_subdirectory(CompatibilityThreading)
|
||||
add_subdirectory(CompatibilityPacks)
|
||||
|
||||
# This is a convenience target to have the list
|
||||
# of all the compatibility libraries needed to build
|
||||
@@ -63,6 +64,7 @@ if(SWIFT_STDLIB_SUPPORT_BACK_DEPLOYMENT)
|
||||
target_link_libraries(HostCompatibilityLibs INTERFACE
|
||||
swiftCompatibilityConcurrency${vsuffix}
|
||||
swiftCompatibilityDynamicReplacements${vsuffix}
|
||||
swiftCompatibilityPacks${vsuffix}
|
||||
swiftCompatibility50${vsuffix}
|
||||
swiftCompatibility51${vsuffix}
|
||||
swiftCompatibility56${vsuffix})
|
||||
|
||||
44
stdlib/toolchain/CompatibilityPacks/CMakeLists.txt
Normal file
44
stdlib/toolchain/CompatibilityPacks/CMakeLists.txt
Normal file
@@ -0,0 +1,44 @@
|
||||
set(library_name "swiftCompatibilityPacks")
|
||||
|
||||
include_directories("include/" "${SWIFT_STDLIB_SOURCE_DIR}")
|
||||
|
||||
set(CMAKE_C_VISIBILITY_PRESET hidden)
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)
|
||||
|
||||
add_compile_definitions(SWIFT_COMPATIBILITY_PACKS)
|
||||
add_swift_target_library("${library_name}" STATIC
|
||||
Metadata.cpp
|
||||
|
||||
TARGET_SDKS ${SWIFT_DARWIN_PLATFORMS}
|
||||
|
||||
C_COMPILE_FLAGS
|
||||
${CXX_COMPILE_FLAGS}
|
||||
"-D__STDC_WANT_LIB_EXT1__=1"
|
||||
LINK_FLAGS ${CXX_LINK_FLAGS}
|
||||
INCORPORATE_OBJECT_LIBRARIES swiftCompatibilityThreading
|
||||
SWIFT_COMPILE_FLAGS ${SWIFT_STANDARD_LIBRARY_SWIFT_FLAGS}
|
||||
DEPLOYMENT_VERSION_OSX ${COMPATIBILITY_MINIMUM_DEPLOYMENT_VERSION_OSX}
|
||||
DEPLOYMENT_VERSION_IOS ${COMPATIBILITY_MINIMUM_DEPLOYMENT_VERSION_IOS}
|
||||
DEPLOYMENT_VERSION_TVOS ${COMPATIBILITY_MINIMUM_DEPLOYMENT_VERSION_TVOS}
|
||||
DEPLOYMENT_VERSION_WATCHOS ${COMPATIBILITY_MINIMUM_DEPLOYMENT_VERSION_WATCHOS}
|
||||
|
||||
MACCATALYST_BUILD_FLAVOR "zippered"
|
||||
|
||||
INSTALL_IN_COMPONENT compiler
|
||||
INSTALL_WITH_SHARED)
|
||||
|
||||
|
||||
# FIXME: We need a more flexible mechanism to add lipo targets generated by
|
||||
# add_swift_target_library to the ALL target. Until then this hack is necessary
|
||||
# to ensure these libraries build.
|
||||
foreach(sdk ${SWIFT_SDKS})
|
||||
set(target_name "${library_name}-${SWIFT_SDK_${sdk}_LIB_SUBDIR}")
|
||||
if(NOT TARGET "${target_name}")
|
||||
continue()
|
||||
endif()
|
||||
|
||||
set_target_properties("${target_name}"
|
||||
PROPERTIES
|
||||
EXCLUDE_FROM_ALL FALSE)
|
||||
endforeach()
|
||||
164
stdlib/toolchain/CompatibilityPacks/Metadata.cpp
Normal file
164
stdlib/toolchain/CompatibilityPacks/Metadata.cpp
Normal file
@@ -0,0 +1,164 @@
|
||||
//===--- Metadata.cpp -----------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Backward deployment of swift_allocateMetadataPack() and
|
||||
// swift_allocateWitnessTablePack() runtime entry points.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../../public/runtime/MetadataCache.h"
|
||||
|
||||
using namespace swift;
|
||||
|
||||
/// Copy and paste a symbol that needs to exist.
|
||||
void *MetadataAllocator::Allocate(size_t size, size_t alignment) {
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
/// Avoid depending on non-inline parts of llvm::hashing.
|
||||
inline llvm::hash_code our_hash_integer_value(uint64_t value) {
|
||||
const char *s = reinterpret_cast<const char *>(&value);
|
||||
const uint64_t a = llvm::hashing::detail::fetch32(s);
|
||||
return llvm::hashing::detail::hash_16_bytes(
|
||||
(a << 3), llvm::hashing::detail::fetch32(s + 4));
|
||||
}
|
||||
|
||||
static inline llvm::hash_code our_hash_combine(llvm::hash_code seed, llvm::hash_code v) {
|
||||
return seed ^ (v + 0x9e3779b9 + (seed<<6) + (seed>>2));
|
||||
}
|
||||
|
||||
/// Copy and paste from Metadata.cpp.
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename PackType>
|
||||
class PackCacheEntry {
|
||||
public:
|
||||
size_t Count;
|
||||
|
||||
const PackType * const * getElements() const {
|
||||
return reinterpret_cast<const PackType * const *>(this + 1);
|
||||
}
|
||||
|
||||
const PackType ** getElements() {
|
||||
return reinterpret_cast<const PackType **>(this + 1);
|
||||
}
|
||||
|
||||
struct Key {
|
||||
const PackType *const *Data;
|
||||
const size_t Count;
|
||||
|
||||
size_t getCount() const {
|
||||
return Count;
|
||||
}
|
||||
|
||||
const PackType *getElement(size_t index) const {
|
||||
assert(index < Count);
|
||||
return Data[index];
|
||||
}
|
||||
|
||||
friend llvm::hash_code hash_value(const Key &key) {
|
||||
llvm::hash_code hash = 0;
|
||||
for (size_t i = 0; i != key.getCount(); ++i) {
|
||||
hash = our_hash_combine(hash, our_hash_integer_value(
|
||||
reinterpret_cast<uint64_t>(key.getElement(i))));
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
|
||||
PackCacheEntry(const Key &key);
|
||||
|
||||
intptr_t getKeyIntValueForDump() {
|
||||
return 0; // No single meaningful value here.
|
||||
}
|
||||
|
||||
bool matchesKey(const Key &key) const {
|
||||
if (key.getCount() != Count)
|
||||
return false;
|
||||
for (unsigned i = 0; i != Count; ++i) {
|
||||
if (key.getElement(i) != getElements()[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
friend llvm::hash_code hash_value(const PackCacheEntry<PackType> &value) {
|
||||
llvm::hash_code hash = 0;
|
||||
for (size_t i = 0; i != value.Count; ++i) {
|
||||
hash = our_hash_combine(hash, our_hash_integer_value(
|
||||
reinterpret_cast<uint64_t>(value.getElements()[i])));
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
static size_t getExtraAllocationSize(const Key &key) {
|
||||
return getExtraAllocationSize(key.Count);
|
||||
}
|
||||
|
||||
size_t getExtraAllocationSize() const {
|
||||
return getExtraAllocationSize(Count);
|
||||
}
|
||||
|
||||
static size_t getExtraAllocationSize(unsigned count) {
|
||||
return count * sizeof(const Metadata * const *);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename PackType>
|
||||
PackCacheEntry<PackType>::PackCacheEntry(
|
||||
const typename PackCacheEntry<PackType>::Key &key) {
|
||||
Count = key.getCount();
|
||||
|
||||
for (unsigned i = 0; i < Count; ++i)
|
||||
getElements()[i] = key.getElement(i);
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
/// The uniquing structure for metadata packs.
|
||||
static SimpleGlobalCache<PackCacheEntry<Metadata>,
|
||||
MetadataPackTag> MetadataPacks;
|
||||
|
||||
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
|
||||
const Metadata * const *
|
||||
swift_allocateMetadataPack(const Metadata * const *ptr, size_t count) {
|
||||
if (MetadataPackPointer(reinterpret_cast<uintptr_t>(ptr)).getLifetime()
|
||||
== PackLifetime::OnHeap)
|
||||
return ptr;
|
||||
|
||||
PackCacheEntry<Metadata>::Key key{ptr, count};
|
||||
auto bytes = MetadataPacks.getOrInsert(key).first->getElements();
|
||||
|
||||
MetadataPackPointer pack(bytes, PackLifetime::OnHeap);
|
||||
assert(pack.getNumElements() == count);
|
||||
return pack.getPointer();
|
||||
}
|
||||
|
||||
/// The uniquing structure for witness table packs.
|
||||
static SimpleGlobalCache<PackCacheEntry<WitnessTable>,
|
||||
WitnessTablePackTag> WitnessTablePacks;
|
||||
|
||||
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
|
||||
const WitnessTable * const *
|
||||
swift_allocateWitnessTablePack(const WitnessTable * const *ptr, size_t count) {
|
||||
if (WitnessTablePackPointer(reinterpret_cast<uintptr_t>(ptr)).getLifetime()
|
||||
== PackLifetime::OnHeap)
|
||||
return ptr;
|
||||
|
||||
PackCacheEntry<WitnessTable>::Key key{ptr, count};
|
||||
auto bytes = WitnessTablePacks.getOrInsert(key).first->getElements();
|
||||
|
||||
WitnessTablePackPointer pack(bytes, PackLifetime::OnHeap);
|
||||
assert(pack.getNumElements() == count);
|
||||
return pack.getPointer();
|
||||
}
|
||||
7
test/Driver/compatibility_packs.swift
Normal file
7
test/Driver/compatibility_packs.swift
Normal file
@@ -0,0 +1,7 @@
|
||||
// RUN: %target-swift-frontend -print-target-info -runtime-compatibility-version 5.8 | %FileCheck %s
|
||||
|
||||
// REQUIRES: OS=macosx
|
||||
|
||||
// CHECK: "libraryName": "swiftCompatibilityPacks",
|
||||
// CHECK-NEXT: "filter": "all",
|
||||
// CHECK-NEXT: "forceLoad": false
|
||||
@@ -3,9 +3,6 @@
|
||||
|
||||
// REQUIRES: executable_test
|
||||
|
||||
// UNSUPPORTED: use_os_stdlib
|
||||
// UNSUPPORTED: back_deployment_runtime
|
||||
|
||||
import StdlibUnittest
|
||||
|
||||
var types = TestSuite("VariadicGenericCaptures")
|
||||
|
||||
Reference in New Issue
Block a user