Mobile Development 18 min read

Deep Dive into Swift Array Implementation and Copy‑On‑Write Mechanics

This article provides a comprehensive, low‑level exploration of Swift's Array type, detailing its memory layout, the SIL generation process, buffer allocation, internal structures such as _ArrayBuffer and _ContiguousArrayStorage, and the copy‑on‑write behavior that governs mutation and reference counting.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
Deep Dive into Swift Array Implementation and Copy‑On‑Write Mechanics

The article begins by presenting a crash scenario caused by mutating a Swift Array while iterating, highlighting that Array is a struct whose underlying storage is a reference‑type buffer.

It then walks through the compilation pipeline: source code is compiled to SIL using swiftc -emit-sil , and the generated SIL shows calls to @Swift._allocateUninitializedArray , which returns a tuple containing an Array instance and a raw pointer to the allocated memory.

Key source snippets illustrate the definition of Array as a frozen struct with a single _buffer property, and the internal buffer types ( _ArrayBuffer , _ContiguousArrayBuffer , _ArrayBody ) that hold metadata such as count, capacity, and a pointer to the contiguous storage.

Allocation is performed by Builtin.allocWithTailElems_1 , which ultimately calls swift::swift_allocObject to reserve heap space for a _ContiguousArrayStorage object. The buffer is then adopted via _adoptStorage , linking the newly allocated storage to the Array instance.

The article explains how the capacity is stored in a packed _capacityAndFlags field, requiring a bit‑shift to extract the actual capacity, and shows the relevant Swift source for initializing _ArrayBody and _SwiftArrayBodyStorage .

Further, it demonstrates how the first element address is obtained using the built‑in projectTailElems operation, which projects the tail‑allocated elements of the storage class.

In the extension section, the copy‑on‑write (COW) mechanism is examined. The append method invokes _makeUniqueAndReserveCapacityIfNotUnique , which checks the strong reference count of the underlying storage; if the count is non‑zero, a new buffer is allocated and the elements are moved or copied, ensuring unique ownership before mutation.

Practical debugging examples using LLDB illustrate the memory addresses of the Array struct, its buffer reference, and the actual stored integers, confirming the theoretical analysis.

Finally, the article summarizes that Swift arrays, despite being value‑type structs, store their elements on the heap, and their COW behavior relies on reference‑count checks of the internal storage to decide when to duplicate memory.

Memory ManagementSwiftarraycopy-on-writeSILLow-Level Debugging
Sohu Tech Products
Written by

Sohu Tech Products

A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.