diff --git a/include/swift/Frontend/BackDeploymentLibs.def b/include/swift/Frontend/BackDeploymentLibs.def index 9f12ae773e7dc..9f3063d1c36c5 100644 --- a/include/swift/Frontend/BackDeploymentLibs.def +++ b/include/swift/Frontend/BackDeploymentLibs.def @@ -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 diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp index 1503fe0246cee..5e744db3a85e3 100644 --- a/lib/Basic/TargetInfo.cpp +++ b/lib/Basic/TargetInfo.cpp @@ -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) { diff --git a/lib/Driver/DarwinToolChains.cpp b/lib/Driver/DarwinToolChains.cpp index f3969819de929..f796fdaf42b60 100644 --- a/lib/Driver/DarwinToolChains.cpp +++ b/lib/Driver/DarwinToolChains.cpp @@ -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" } diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 74630bbafff90..869af287d5170 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -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); diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp index 67049d6b48054..843df87a46383 100644 --- a/lib/IRGen/GenDecl.cpp +++ b/lib/IRGen/GenDecl.cpp @@ -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 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" } } diff --git a/stdlib/toolchain/CMakeLists.txt b/stdlib/toolchain/CMakeLists.txt index c32c7f3ffb51f..de2b0eaa73346 100644 --- a/stdlib/toolchain/CMakeLists.txt +++ b/stdlib/toolchain/CMakeLists.txt @@ -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}) diff --git a/stdlib/toolchain/CompatibilityPacks/CMakeLists.txt b/stdlib/toolchain/CompatibilityPacks/CMakeLists.txt new file mode 100644 index 0000000000000..d918614430faa --- /dev/null +++ b/stdlib/toolchain/CompatibilityPacks/CMakeLists.txt @@ -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() diff --git a/stdlib/toolchain/CompatibilityPacks/Metadata.cpp b/stdlib/toolchain/CompatibilityPacks/Metadata.cpp new file mode 100644 index 0000000000000..595e05dac7b6c --- /dev/null +++ b/stdlib/toolchain/CompatibilityPacks/Metadata.cpp @@ -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(&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 +class PackCacheEntry { +public: + size_t Count; + + const PackType * const * getElements() const { + return reinterpret_cast(this + 1); + } + + const PackType ** getElements() { + return reinterpret_cast(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(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 &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(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 +PackCacheEntry::PackCacheEntry( + const typename PackCacheEntry::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, + MetadataPackTag> MetadataPacks; + +SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) +const Metadata * const * +swift_allocateMetadataPack(const Metadata * const *ptr, size_t count) { + if (MetadataPackPointer(reinterpret_cast(ptr)).getLifetime() + == PackLifetime::OnHeap) + return ptr; + + PackCacheEntry::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, + WitnessTablePackTag> WitnessTablePacks; + +SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) +const WitnessTable * const * +swift_allocateWitnessTablePack(const WitnessTable * const *ptr, size_t count) { + if (WitnessTablePackPointer(reinterpret_cast(ptr)).getLifetime() + == PackLifetime::OnHeap) + return ptr; + + PackCacheEntry::Key key{ptr, count}; + auto bytes = WitnessTablePacks.getOrInsert(key).first->getElements(); + + WitnessTablePackPointer pack(bytes, PackLifetime::OnHeap); + assert(pack.getNumElements() == count); + return pack.getPointer(); +} diff --git a/test/Driver/compatibility_packs.swift b/test/Driver/compatibility_packs.swift new file mode 100644 index 0000000000000..fa45cb9dcd147 --- /dev/null +++ b/test/Driver/compatibility_packs.swift @@ -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 diff --git a/test/Interpreter/variadic_generic_captures.swift b/test/Interpreter/variadic_generic_captures.swift index 88d118b5d7aa7..6ca7215b084c3 100644 --- a/test/Interpreter/variadic_generic_captures.swift +++ b/test/Interpreter/variadic_generic_captures.swift @@ -3,9 +3,6 @@ // REQUIRES: executable_test -// UNSUPPORTED: use_os_stdlib -// UNSUPPORTED: back_deployment_runtime - import StdlibUnittest var types = TestSuite("VariadicGenericCaptures")