Backward deployment shim for swift_allocate{Metadata,WitnessTable}Pack()

This commit is contained in:
Slava Pestov
2023-05-10 17:39:40 -04:00
parent b116d354dc
commit c2338aa0f6
10 changed files with 257 additions and 29 deletions

View File

@@ -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

View File

@@ -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) {

View File

@@ -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"
}

View File

@@ -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);

View File

@@ -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"
}
}

View File

@@ -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})

View 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()

View 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();
}

View 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

View File

@@ -3,9 +3,6 @@
// REQUIRES: executable_test
// UNSUPPORTED: use_os_stdlib
// UNSUPPORTED: back_deployment_runtime
import StdlibUnittest
var types = TestSuite("VariadicGenericCaptures")