0.19.0
A minor release on top of 0.17.1, carrying three pieces of work: the ABI model no longer drags in the symbol index and the demangler (source-breaking β the migration list is below), dump and interface got 17β23% faster, and a class's vtable members are attributed correctly when the linker has folded several method bodies onto one address. There is no 0.18.0 release; everything written under that number ships here.
What's new
- Reading ABI descriptors no longer builds the image's symbol index.
MachOSwiftSectionnow depends onMachOBasealone β no symbol index, no demangler β so touching a method descriptor's implementation pointer costs pointer arithmetic instead of demangling every symbol in the image on first access. Symbol attribution moved one layer up, toSwiftInspection. Two new library products come with the split:MachOBase(readers, resolvers, pointers) andMachOFoundation(that plus the symbol index and dependency resolution). dumpandinterfaceare faster with no flags to set. The speedup comes from where the demangler runs, so it applies to every reader path and every output style. It needs macOS 15 / iOS 18 (or the aligned tvOS 18 / watchOS 11 / visionOS 2) at runtime; below that, and off Darwin, everything behaves as in0.17.1.--jobs N(diff,evolution) β how many versions to index at once. Defaults to the processor count;--jobs 1restores the previous one-at-a-time order. Results are identical either way. In the library it isprepare(maximumConcurrentPreparations:).- Console diagnostics name their input.
diffprefixes its lines[old]/[new],evolutionprefixes each version's label, so a warning from a five-version run is attributable. stderr only, as before. MACHO_SWIFT_SECTION_LARGE_STACK_EXECUTOR=0turns the faster path off process-wide, for a host that manages its own task executor.0/false/no/offall mean off; anything else, or unset, means on.
Fixes
- A class's vtable members no longer borrow a nested type's names. Identical code folding merges byte-identical method bodies onto one address β SwiftUICore has one carrying 2878 symbols β and a member's name used to be read from there, so
SwiftUI.GraphHostprinted three of its nestedGraphHost.Data's coroutine resume functions as its own methods. Names now come from each member's own method-descriptor symbol, which folding cannot reach. On SwiftUICore (iOS 18.5 arm64): 828 declaration lines change, all 7 nested-type bleeds are gone with none introduced, andSymbol not founddrops from 358 to 0. - Two new comments where a name cannot be trusted. The ~28% of slots carrying no method-descriptor symbol still fall back to the implementation address; when that address is folded, the output now says so (
// Attribution: ambiguous β N symbols folded at this address) rather than presenting a guess as fact. A slot whose body was removed by dead-method elimination is annotated instead of failing to resolve. Both comments are always on; their wording and theNcount are being tuned for the next release.
Breaking
Source level β this package is distributed as source, so every downstream recompiles:
descriptor.implementationSymbols(in: machO)β drop thetry, addimport SwiftInspection.descriptor.implementationSymbols(in: context)β removed. Usetry descriptor.implementationAddress(in: context)for the location.Symbols.resolve(from:in:)β removed. CallmachO.symbols(offset:)(MachOSymbols).symbols(offset:) asyncβ removed. It was identical to the synchronous form, and anasynccaller bound to it and then demandedawait.MachOSymbols.Symbol/.Symbols/.SymbolOrElementβ nowMachOResolving.β¦, or unqualified.import MachOSymbolPointersβ remove it;SymbolOrElementPointerlives inMachOPointers.ResilientWitness.implementationOffsetisInt?, andimplementationAddress(in:)returnsString?.- A file that reached
SymbolIndexStore,DemangledSymbolorDependencyClosurethroughimport MachOSwiftSectionalone now needsimport MachOFoundation, and its target must declare that product (.product(name: "MachOFoundation", package: "MachOSwiftSection")). Those types used to arrive through a re-export, so no product existed for them β and reaching a module through the build directory without declaring it works by accident in a monolithic SwiftPM build, then fails under explicit modules.
Measured
Release build, host dyld shared cache, macOS 26.5.2 on a 10-core Apple Silicon Mac.
| SwiftUICore | SwiftUI | |
|---|---|---|
dump |
48.8 s β 40.6 s | 79.4 s β 61.3 s |
interface |
56.4 s β 47.0 s | 87.5 s β 71.2 s |
evolution over three archived SwiftUI caches (macOS 15.5 / 26.5.2 / 27.0 beta 6) roughly halves with the default --jobs: --interface 307 s β 152 s, lineage report 282 s β 139 s.
Compatibility
dump/interfaceoutput changes in two places, both deliberate: the vtable attribution fix above, and β only under--emit-member-addressesβ a resilient witness with a null implementation pointer no longer gets an address comment (the old line printed the pointer field's own position as if it were code). Everything else is byte-identical to0.17.1, verified with the rendering A/B harness.- Dependency floor: swift-demangling
0.6.3 ..< 0.7.0(was0.6.0 ..< 0.7.0). Do not pin 0.6.1 β it sloweddump/interface3β4Γ and 0.6.2 fixed it. Other pins unchanged from0.17.1. - Snapshot
formatVersionunchanged.
Requirements
- Swift 6.2+
- Xcode 26.0+
Full design and measurements: evolution proposals 0018, 0019 and 0020; implementation notes SelfContainedABILayer.md and LargeStackTaskExecutorAdoption.md.