apple/swift
Runtime
Active contributors: rjmccall, mikeash, ktoso, al45tair
Purpose
stdlib/public/runtime/ is the C/C++ runtime library that supports every Swift program at runtime. It implements:
- Reference counting (
swift_retain,swift_release,swift_unownedRetain, ...). - Type metadata creation, lookup, and caching.
- Witness tables and protocol conformance lookup.
- Dynamic casting (
as?,as!, conditional protocol conformance). - Swift error type machinery (
swift_allocError,swift_willThrow, ...). - The Concurrency runtime entry points (in
stdlib/public/Concurrency/, with this directory hosting their support). - Image inspection (load
Mach-O/ELF/COFFsections looking for type/conformance records). - Crash handlers and the optional in-process backtracer.
The runtime is linked into every Swift binary (statically on Linux, as libswiftCore.dylib on Apple platforms).
Directory layout
stdlib/public/runtime/ (~200 files)
├── HeapObject.cpp # ARC, allocation
├── Heap.cpp # malloc/free/realloc wrappers (zone-aware on Apple)
├── Metadata.cpp # type metadata cache + creation
├── MetadataLookup.cpp # mangled-name → metadata
├── ProtocolConformance.cpp # conformance lookup
├── DynamicCast.cpp # `as?`, `as!`, including bridging to ObjC
├── Casting.cpp # conditional cast helpers
├── KeyPaths.cpp # runtime support for KeyPath
├── ErrorObject*.cpp / ErrorObject.mm # `Error` (Swift) + `NSError` bridging
├── ExistentialContainer.cpp # `any P` representation
├── Exception.cpp # cleanup machinery for `throws`
├── Exclusivity.cpp # `Law of Exclusivity` runtime checks
├── Backtrace.cpp + CrashHandler*.cpp # crash + backtrace support
├── ImageInspection*.cpp # per-platform section walkers
├── Demangle.cpp # link to the demangler
├── ReflectionMirror.cpp # `Mirror`
├── EnvironmentVariables.def # SWIFT_DEBUG_* knobs
├── SwiftDtoa.cpp # stdlib's float-to-string
└── ...
include/swift/Runtime/ # public headers
├── HeapObject.h, Metadata.h, ...
├── Config.h
└── RuntimeFunctions.def # the ABI list of runtime entry points
stdlib/public/Concurrency/ # Concurrency runtime + Swift overlay
└── (mixed C++/Swift; see libraries/concurrency.md)Key abstractions
| Type / function | File | Description |
|---|---|---|
HeapObject |
stdlib/public/SwiftShims/swift/shims/HeapObject.h |
Header of every Swift class instance: metadata pointer + ref counts. |
Metadata |
include/swift/ABI/Metadata.h |
Runtime metadata structure for any Swift type. |
ValueWitnessTable |
include/swift/ABI/ValueWitness.h |
Function table for size/copy/destroy of opaque values. |
ProtocolConformanceDescriptor |
include/swift/ABI/Metadata.h |
Records that map (type, protocol) → witness table. |
swift_retain / swift_release |
stdlib/public/runtime/HeapObject.cpp |
ARC entry points. |
swift_allocObject |
stdlib/public/runtime/HeapObject.cpp |
Allocate a class instance. |
swift_dynamicCast |
stdlib/public/runtime/DynamicCast.cpp |
The catch-all dynamic-cast entry point. |
swift_getGenericMetadata |
stdlib/public/runtime/Metadata.cpp |
Build (or look up cached) generic metadata. |
How it works
Reference counting
Every class instance starts with a HeapObject header: a metadata pointer plus 64 bits of strong+unowned+weak ref counts (include/swift/ABI/HeapObject.h). swift_retain does an inline atomic add; the slow path handles deinit, weak references, and bridging to Objective-C (isa swizzling).
Metadata
Every Swift type has a runtime metadata record. For non-generic types, the record is emitted by IRGen at compile time and lives in a known section (__swift5_types). For generic types, the record is computed at first use by swift_getGenericMetadata, populating a field-by-field instantiation pattern emitted by IRGen.
graph LR
Compiler[IRGen] -->|"emit"| Section["__swift5_types"]
Section -->|"loaded by image inspection"| Runtime
Runtime --> Cache[Metadata cache]
UserCode["MyType<Int>.self"] --> Cache
Cache -->|miss| Build[swift_getGenericMetadata]
Build --> CacheConformance lookup
type as? P boils down to looking up the protocol conformance for (MyType, P). The runtime walks the loaded image's __swift5_proto and __swift5_protos sections at startup (or lazily, depending on platform) and builds a hash table keyed by (type descriptor, protocol descriptor). Code in ProtocolConformance.cpp and RuntimeProtocolConformanceLookup.cpp.
Dynamic casting
DynamicCast.cpp is the heart of as?, as!, and is. It dispatches on metadata kind: classes, structs/enums, existentials, tuples, functions. It also bridges between Swift and Objective-C representations (SwiftValue boxes) so a Swift String can be cast to NSString and vice versa.
Error handling
Swift's throws is a return-by-error-result convention, not C++ exceptions. The runtime helpers swift_allocError, swift_willThrow, swift_errorRetain manage the heap-allocated error box (ErrorObject*).
Concurrency runtime
stdlib/public/Concurrency/ houses the Concurrency runtime: tasks, executors, actors, async/await machinery. See Concurrency. It is heavy on C++ (Actor.cpp, AsyncLet.cpp, Task.cpp) and exposes Swift overlay types via Actor.swift, Task.swift, etc. The runtime calls into platform-specific schedulers (DispatchExecutor.cpp, CooperativeGlobalExecutor.cpp).
Backtracing and crash handling
Backtrace.cpp plus per-platform CrashHandler{Linux,MacOS,Windows}.cpp register a signal handler / vectored exception handler that captures a backtrace and writes a structured crash log. Configured via the SWIFT_BACKTRACE environment variable; see docs/Backtracing.rst.
Demangling
The demangler exists in two copies:
lib/Demangling/-- linked into the compiler/tools.stdlib/public/runtime/Demangle.cpp(using shared sources fromstdlib/public/Demangling/) -- linked into the runtime so user programs can demangle symbols at runtime (e.g., forswift_demangle).
Both share the same source files via include lists; changes must be made in tandem.
Integration points
- IRGen emits calls to the runtime (
include/swift/Runtime/RuntimeFunctions.def). - Standard library uses the runtime under the hood:
Arrayallocation,Dictionarystorage,Stringcocoa bridging. - Concurrency runtime is partially in
stdlib/public/Concurrency/;stdlib/public/runtime/provides shared support (heap, metadata, exceptions). swift-inspectqueries a running process vialib/SwiftRemoteMirror/-- the runtime exposes a stable section format for this.
Entry points for modification
- Adding a new runtime function: declare in
include/swift/Runtime/RuntimeFunctions.def, implement instdlib/public/runtime/, optionally update IRGen to emit calls. - Changing metadata layout: see
include/swift/ABI/Metadata.handdocs/ABI/TypeMetadata.rst. ABI-breaking; consult code owners. - Diagnosing a runtime crash:
SWIFT_DEBUG_RUNTIME_ENVIRONMENT_VARIABLES=1lists every supported flag.SWIFT_DETERMINISTIC_HASHING=1reproduces hash-table flakes.SWIFT_BACKTRACE=enable=yes,sanitize=presetsymbolicates crashes. - Adding a debug environment variable: edit
EnvironmentVariables.def.
Related pages
- IRGen -- the compile-time partner.
- Standard library -- the user-facing layer.
- Concurrency -- the largest single runtime extension.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.
Previous
Serialization and module loading
Next
SwiftCompilerSources