ABI 추가 공부하기..

Tabber·2026년 2월 1일

Swift

목록 보기
14/15

ABI를 계속 봐도 잘 이해가 안가서, 다시 공부해보기로 했다.

참고로 해당 내용은 swift github 레포지토리에 docs 내용 중 ABI 관련 내용을 기반으로 공부해보았다.

ABI

API가 소스 코드 수준에서의 약속이라면, ABI는 컴파일된 기계어(바이너리) 수준에서의 약속이에요!

ABI의 핵심적인 기둥들을 정리해보자.

Swift 호출 규약 (Calling Convention)

Swift는 C나 Objective-C의 규약을 그대로 따르지 않고, Swift 만의 효율적인 방식을 사용해요.

레지스터 활용

  • Swift는 가능한 한 많은 정보를 레지스터에 실어 보내려고 해요. 예를 들어, self 나 에러 정보 (Error return )를 담기 위한 전용 레지스터를 지정해두어요.

소유권 전달 (Ownership)

  • 함수에 인자를 넘길 때, 단순히 값을 복사하는 것이 아니라 “이 값의 메모리 관리 책임이 누구에게 있는가”를 정해요.
    • Owned : 함수가 인자의 소유권을 가져가요. (함수가 끝나면 해제 책임이 있음)
    • Guaranteed : 함수가 실행되는 동안만 유효함을 보장받으며, 소유권은 호출자가 유지해요. (self 전달 시 주로 사용돼요.)
  • Inout 인자 : inout 파라미터는 항상 주소값(Address)을 통해 전달돼요.

데이터 레이아웃 (Type Layout)

메모리에 데이터가 어떤 순서와 간격으로 배치되는지에 대한 규칙이에요.

Struct & Tuple

  • 선언된 순서대로 메모리에 배치돼요. Swift는 C와 달리 최적화된 패킹을 통해 메모리 낭비를 줄이려 노력해요.
  • Enum : 케이스의 개수와 연관 값 (Associated Value)의 유무에 따라 전략이 달라져요.
    • 데이터가 없는 enum은 아주 작은 정수값으로 저장돼요.
    • Extra Inhabitants : 포인터의 nil 처럼 실제로 사용되지 않는 비트 패턴을 활용해 별도의 태그 없이 케이스를 구분하기도 해요.

이름 망글링 (Name Mangling)

컴파일러는 함수 이름, 타입, 모듈 정보를 하나의 고유한 문자열로 변환해요. 바이너리 내에서 심볼이 충돌하지 않게 하기 위함이죠.

Swift 5+ 안정성

  • Swift 5부터 ABI가 안정화되면서 이 망글링 규칙도 고정되었어요. $s 로 시작하는 그 이름들이 그 예입니다.

타입 메타데이터 (Type Metadata)

Swift는 런타임에 타입의 정보를 확인하기 위해 모든 타입마다 메타데이터 레코드를 유지해요.

  • 이 레코드를 통해 런타임에 객체를 복사하거나, 파괴하거나, 제네릭 타입을 실체화하는 등의 작업을 수행해요.

정리

ARM64 아키텍처에서 Swift가 함수를 호출할 때 레지스터를 어떻게 나누어 쓰는지 예시를 보면 ABI의 실체를 더 잘 느낄 수 있어요.

레지스터Swift에서의 용도
x0첫 번째 정수 인자 및 결과값
x20self (컨텍스트 레지스터)
x21Error 결과값 (에러 발생 시 사용)
v0-v7부동 소수점 인자들
profile
iOS 정복중인 Tabber 입니다.

0개의 댓글