Share
Embed
ランタイムライブラリのbackward-deploymentの仕組み
[わいわいswiftc #30 オンライン - connpass](https://iosdiscord.connpass.com/event/223396/)
Yuta Saito
September 24, 2021
Transcript
43 slides
-
͓͠ͳ͕͖ 1. Swiftͷ࣮ߦʹඞཁͳͷ 2. ABI Stability 3. ͳͥόοΫσϓϩΠ͕ඞཁʁ 4. όοΫσϓϩΠͷΈ
5. ConcurrencyϞδϡʔϧͷόοΫσϓϩΠ 5 -
SwiftͷABI Stability ίϯύΠϥͷੜόΠφϦɺϥϯλΠϜͷABIʹ͍ͭͯ ޓੑΛอͭଋ • લํ/ޙํ ͲͪΒʹޓ • ޙํͷํ͕େࣄɻલํ࠷ѱ෦తͰOK •
ABI Stability Manifestʹৄ͍͠ن͕͋Δ https://github.com/apple/swift/blob/main/docs/ABIStabilityManifesto.md 8 -
ABI Stability͕Մೳʹ͢Δ͜ͱ ྫ • Swift 5.0ͰίϯύΠϧͨ͠ϥΠϒϥϦ͕ɺ Swift 5.2ͰίϯύΠϧͨ͠ΞϓϦͰ͑Δɻ • Swift
5.0ͰίϯύΠϧͨ͠ΞϓϦ͕ɺ Swift 5.1ͷϥϯλΠϜͰಈ͘ɻ • Swift 5.2ͰίϯύΠϧͨ͠ΞϓϦ͕ɺ Swift 5.0ͷϥϯλΠϜͰಈ͘ɻ 9 -
ABI Stabilizeલ (~ Swift 5.0) • ֤ΞϓϦ͕ϥϯλΠϜϥΠϒϥϦΛಉࠝ • ΞϓϦͱϥϯλΠϜͷݴޠόʔδϣϯ͕ৗʹҰக ./My.app
├── Frameworks │ └── libswiftCore.dylib ├── Info.plist ├── My └── _CodeSignature 10 -
ABI Stabilizeલ (Swift 5.0 ~) • iOS 13ɺmacOS 10.14.4 ͔ΒOSࣗମʹಉࠝ
• ϥΠϒϥϦΛల։͢ΔϝϞϦΛΞϓϦؒͰڞ༗ • ΞϓϦͷόϯυϧαΠζݮͬͯخ͍͠ • ͕ɺϥϯλΠϜͷόʔδϣϯ͕OS͝ͱʹݻఆ͞Εͯ͠·ͬͨ 11 -
ϥϯλΠϜ͕OSʹೖΔ͜ͱͰى͜Δ ΞϓϦ͕͏ݴޠόʔδϣϯͱϥϯλΠϜόʔδϣϯ͕ඞͣ͠ Ұக͠ͳ͍ ྫ • Swift 5.0ͰίϯύΠϧͨ͠ΞϓϦΛɺ Swift 5.1ͷϥϯλΠϜͰಈ͔͢ɻ ->
ϥϯλΠϜͷޙํޓੑ • Swift 5.2ͰίϯύΠϧͨ͠ΞϓϦΛɺ Swift 5.0ͷϥϯλΠϜͰಈ͔͢ɻ -> ϥϯλΠϜͷલํޓੑ 12 -
ϥϯλΠϜͷޙํޓੑ additiveͰͳ͍มߋ͕ೖΔͱOS͝ͱʹڍಈ͕มΘͬͯࠔΔ • μΠφϛοΫΩϟετͷڍಈ͕มΘͬͯࠔͬͨྫ • SR-1999: Inconsistency when casting Optional
to Any and downcasting to non-Optional • IBLinter Issue #170 14 -
όοΫσϓϩΠͷྲྀΕ # min-deploytarget͔Β࠷খϥϯλΠϜΛܾΊΔ swiftc main.swift -target x86_64-apple-macosx10.15 # OR #
࠷খϥϯλΠϜΛࢦఆ swiftc main.swift -runtime-compatibility-version 5.1 17 -
υϥΠό͕Δ͜ͱ libswiftCompatibility51.aΛϦϯΫ swiftc -emit-object main.swift -o main.o ld main.o \
-force_load /path/to/toolchain/usr/lib/swift/macosx/libswiftCompatibility51.a \ -lswiftCore -o main 18 -
ϦϯΫޙͷόΠφϦ $ du -h main_5_1_compat 56K main_5_1_compat $ objdump --macho
--headers main_5_1_compat Sections: Idx Name Size VMA Type 0 __text 00000f9c 0000000100002d64 TEXT 1 __stubs 000000d8 0000000100003d00 TEXT 2 __stub_helper 000000f0 0000000100003dd8 TEXT 3 __swift5_entry 00000004 0000000100003ec8 DATA 4 __const 00000006 0000000100003ecc DATA 5 __cstring 0000009b 0000000100003ed2 DATA 6 __unwind_info 00000090 0000000100003f70 DATA 7 __got 00000008 0000000100004000 DATA 8 __const 00000008 0000000100004008 DATA 9 __objc_imageinfo 00000008 0000000100004010 DATA 10 __la_symbol_ptr 00000090 0000000100008000 DATA 11 __swift51_hooks 000000b8 0000000100008090 DATA 12 __data 00000009 0000000100008148 DATA 13 __bss 000000c8 0000000100008158 BSS $ du -h main 36K main $ objdump --macho --headers main Sections: Idx Name Size VMA Type 0 __text 0000000c 0000000100003fa4 TEXT 1 __swift5_entry 00000004 0000000100003fb0 DATA 2 __const 00000002 0000000100003fb4 DATA 3 __unwind_info 00000048 0000000100003fb8 DATA 4 __objc_imageinfo 00000008 0000000100004000 DATA 19 -
ϥϯλΠϜؔͷ࣮ଶ #define COMPATIBILITY_OVERRIDE(name, ret, attrs, ccAttrs, namespace, \ typedArgs, namedArgs)
\ attrs ccAttrs ret namespace swift_##name COMPATIBILITY_PAREN(typedArgs) { \ static Override_##name Override; \ static swift_once_t Predicate; \ swift_once( \ &Predicate, [](void *) { Override = getOverride_##name(); }, nullptr); \ if (Override != nullptr) \ return Override(COMPATIBILITY_UNPAREN_WITH_COMMA(namedArgs) \ swift_##name##Impl); \ return swift_##name##Impl COMPATIBILITY_PAREN(namedArgs); \ } COMPATIBILITY_OVERRIDE(dynamicCastClass, const void *, , , swift::, (const void *object, const ClassMetadata *targetType), (object, targetType)) https://github.com/apple/swift/blob/main/stdlib/public/CompatibilityOverride/CompatibilityOverride.h 22 -
ϥϯλΠϜؔͷ࣮ଶʢϚΫϩల։ޙʣ const void * swift::swift_dynamicCastClass(const void *object, const ClassMetadata *targetType)
{ static Override_dynamicCastClass Override; static swift_once_t Predicate; swift_once(&Predicate, [](void *) { Override = getOverride_dynamicCastClass(); }, nullptr); if (Override != nullptr) return Override(object, targetType, swift_dynamicCastClassImpl); return swift_dynamicCastClassImpl(object, targetType); } https://github.com/apple/swift/blob/main/stdlib/public/CompatibilityOverride/CompatibilityOverride.h 23 -
ϑοΫηΫγϣϯ͔Β OverrideSection ߏମΛಡΈग़͢ // ϚΠφʔόʔδϣϯΞοϓ͝ͱʹมΘΔ #define COMPATIBILITY_OVERRIDE_SECTION_NAME __swift54_hooks static OverrideSection
*getOverrideSectionPtr() { static OverrideSection *OverrideSectionPtr; static swift_once_t Predicate; swift_once(&Predicate, [](void *) { size_t Size; OverrideSectionPtr = static_cast<OverrideSection *>( lookupSection("__DATA", COMPATIBILITY_OVERRIDE_SECTION_NAME, &Size)); if (Size < sizeof(OverrideSection)) OverrideSectionPtr = nullptr; }, nullptr); return OverrideSectionPtr; } Override_dynamicCastClass swift::getOverride_dynamicCastClass() { auto *Section = getOverrideSectionPtr(); if (Section == nullptr) return nullptr; return Section->dynamicCastClass; } https://github.com/apple/swift/blob/main/stdlib/public/CompatibilityOverride/CompatibilityOverride.cpp 24 -
ϑοΫηΫγϣϯ in libswiftCompatibility51.a struct OverrideSection { uintptr_t version; #define OVERRIDE(name,
ret, attrs, ccAttrs, namespace, typedArgs, namedArgs) \ Override_ ## name name; #include "CompatibilityOverride.def" }; OverrideSection Swift51Overrides __attribute__((used, section("__DATA,__swift51_hooks"))) = { .version = 0, .conformsToSwiftProtocol = swift51override_conformsToSwiftProtocol, }; 25 -
ෳͷݹ͍ϥϯλΠϜΛαϙʔτ͍ͨ͠ͱ͖ • ෳͷlibswiftCompatibilityX.aΛϦϯΫ͢ΕOK • ϥϯλΠϜࣗͷόʔδϣϯ͚ͷϑοΫηΫγϣϯ͔͠ ಡ·ͳ͍ͷͰׯব͠ͳ͍ swiftc main.swift -runtime-compatibility-version 5.0
# υϥΠό͕ˣΛൃߦ ld main.o \ -force_load /path/to/toolchain/usr/lib/swift/macosx/libswiftCompatibility50.a \ -force_load /path/to/toolchain/usr/lib/swift/macosx/libswiftCompatibility51.a \ -lswiftCore -o main 26 -
ConcurrencyόοΫσϓϩΠͷؔϙΠϯτ • ৽͍͠ڥͰOSಉ࣮ࠝʹΓସ͑ΔͨΊͷαϯΫ͕ඞཁ • γϯϘϧ͕ॏෳ͠ͳ͍Α͏ʹϦωʔϜ͕ඞཁ • ίϯύΠϥ͕ు͘ίʔυαϯΫΛࢀর͢Δඞཁ͋Γ • ޙड़ •
OSಉࠝlibdispatchͷSwift͚ͷ৽ػೳʹґଘͯ͠ΔͷͰ ϑΥʔϧόοΫ͕ඞཁ 33 -
πʔϧνΣΠϯͷϏϧυεΫϦϓτ όοΫσϓϩΠ༻ͷlibswift_Concurrency.dylib͕ϏϧυͰ ͖Δ • /usr/lib/swift-5.5/macosx/ libswift_Concurrency.dylibʹೖΔ • Ϗϧυ͕ग़དྷΔ͚ͩͰɺ͜Ε͚ͩͰ͑ͳ͍ • Add
an option to build the concurrency library for back deployment #39051 35 -
γϯϘϧॏෳ ରԠࡁΈɻଟಈ͘ Back-deploy creation of global-actor-qualified function type metadata. #39280
• ίϯύΠϥଆͱޓϥΠϒϥϦͷ࣮͕ऴΘͬͯΔ • ޓϥΠϒϥϦ libswiftCompatibilityConcurrency.a • طଘͷΈͱͪΐͬͱࣅͯΔ 37 -
// In "libswiftCore.dylib" in iOS 15 const FunctionTypeMetadata * swift_getFunctionTypeMetadataGlobalActor(...);
// In "/usr/lib/swift-5.5/macosx/libswift_Concurrency.dylib" const FunctionTypeMetadata * swift_getFunctionTypeMetadataGlobalActorStandalone(...); // In "libswiftCompatibilityConcurrency.a" const FunctionTypeMetadata * swift_getFunctionTypeMetadataGlobalActorBackDeploy(...) { static BuilderFn builderFn; static dispatch_once_t builderToken; dispatch_once(&builderToken, ^{ // Prefer the function from the Swift runtime if it is available. builderFn = reinterpret_cast<BuilderFn>( dlsym(RTLD_DEFAULT, "swift_getFunctionTypeMetadataGlobalActor")); if (builderFn) return; builderFn = reinterpret_cast<BuilderFn>( dlsym(RTLD_DEFAULT, "swift_getFunctionTypeMetadataGlobalActorStandalone")); }); return builderFn(...); } https://github.com/apple/swift/blob/main/stdlib/public/BackDeployConcurrency/Metadata.cpp 38 -
Concurrency back-deployؔ࿈ϦϯΫ • Make the back-deployed concurrency dylibs depend only
on what's available in older runtimes • Make swift_async_extendedFramePointerFlags = 0 in back- deployed configurations • Back-deploy creation of global-actor-qualified function type metadata. • Use private concurrent queues for back-deployed 41 -
ΞϓϦʹউखʹಉࠝ͢Ε… ཧతʹಈ͘ɻ͕ɺ • ࠷৽ͷXcodeϥϯλΠϜಉࠝόϯυϧΛαϙʔτͯ͠ͳ ͍ɻ • SwiftͷoverlayΛશ෦ೖΕΔඞཁ͕͋ΔͷͰόΠφϦαΠζ૿ ͑Δ • SwiftͷOSϥΠϒϥϦ͕͑ͳ͍
like SwiftUI https://swift.org/blog/abi-stability-and-apple/ 42