Swift - Under the Hood
- 1. Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Swift Under the Hood
- 2. InfoQ.com: News & Community Site
• 750,000 unique visitors/month
• Published in 4 languages (English, Chinese, Japanese and Brazilian
Portuguese)
• Post content from our QCon conferences
• News 15-20 / week
• Articles 3-4 / week
• Presentations (videos) 12-15 / week
• Interviews 2-3 / week
• Books 1 / month
Watch the video with slide
synchronization on InfoQ.com!
http://www.infoq.com/presentations
/swift-llvm
- 3. Presented at QCon London
www.qconlondon.com
Purpose of QCon
- to empower software development by facilitating the spread of
knowledge and innovation
Strategy
- practitioner-driven conference designed for YOU: influencers of
change and innovation in your teams
- speakers and topics driving the evolution and innovation
- connecting and catalyzing the influencers and innovators
Highlights
- attended by more than 12,000 delegates since 2007
- held in 9 cities worldwide
- 4. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
▸ About This Talk
• Overview
• Where did Swift come from?
• What makes Swift fast?
• Where is Swift going?
• Alex Blewitt @alblue
• NeXT owner and veteran Objective-C programmer
• Author of Swift Essentials http://swiftessentials.org
Based on Swift 1.1,
the public release in
March 2015
- 5. Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Where did Swift
come from?
- 6. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Pre-history
• Story starts in 1983 with Objective-C
• Created as a Smalltalk like runtime on top of C
• NeXT licensed Objective-C in 1988
• NextStep released in 1989 (and NS prefix)
• Apple bought NeXT in 1996
• OSX Server in 1999
• OSX 10.0 Beta in 2000, released in 2001
- 7. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Objective-C
• Originally implemented as a pre-processor for C
• Rewrote Objective-C code as C code
• Enhanced and merged into GCC
• Compiler integrated under GPL
• Runtime libraries open source (and GNUStep)
http://www.opensource.apple.com/source/
objc4/objc4-208/runtime/objc.h
/*!
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.!
* objc.h!
* Copyright 1988-1996, NeXT Software, Inc.!
*/!
- 8. Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Timeline
C
1972
Objective-C
1983
Smalltalk
1972
Objective-C
2.0 2007
C++
1983
C++07
2007
C++11
2011
C++14
2014
LLVM 1.0
2003
Clang 1.0
2009
Swift 1.0
2014
Static dispatch
Dynamic dispatch
- 9. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Static and Dynamic?
• Static dispatch (used by C, C++, Swift)
• Function calls are known precisely
• Compiler generates call/callq to direct symbol
• Fastest, and allows for optimisations
• Dynamic dispatch (used by Objective-C, Swift)
• Messages are dispatched through objc_msgSend
• Effectively call(cache["methodName"])
Swift can generate
Objective-C classes
and use runtime
- 10. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
objc_msgSend
• Every Objective-C message calls objc_msgSend
• Hand tuned assembly – fast, but still overhead
40
50
60
70
80
90
100
110
Leopard Snow Leopard Lion Mountain Lion Mavericks
107
104
47 47
44
Removal of special-
case GC handling
CPU, registers
(_cmd, self),
energy🔋
- 11. Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Static Dispatch
a() -> b() -> c()
a b c
Dynamic Dispatch
[a:] -> [b:] -> [c:]
a b c
objc_msgSend objc_msgSend
Optimises
to abc
Cannot be
optimised
- 12. Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
What makes
Swift fast?
- 13. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Memory optimisation
• Contiguous arrays of data vs objects
• NSArray
• Diverse
• Memory fragmentation
• Limited memory load benefits for locality
• Array<…>
• Iteration is more performant over memory
- 14. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Optimisations
• Most optimisations rely on inlining
• Instead of a() -> b(), have ab() instead
• Reduces function prologue/epilog (stack/reg spill)
• Reduces branch miss and memory jumps
• May unlock peephole optimisations
• func foo(i:Int) {if i<0 {return}…}
• foo(-1) foo(negative) can be
optimised away completely
Increases code size
- 15. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Link Time Optimisation
• LTO performs whole-program optimisation
• Instead of writing out x86 .o files, writes LLVM
• LLVM linker reads all files, optimises
• Can see optimisations where single file cannot
• final methods and data structures can be inlined
• Structs are always final (no subclassing)
• private (same file) internal (same module)
- 16. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Swift and LLVM
• Swift and clang are both built on LLVM
• Originally stood for Low Level Virtual Machine
• Family of tools (compiler, debugger, linker etc.)
• Abstract assembly language
• Intermediate Representation (IR), Bitcode (BC)
• Infinite register RISC typed instruction set
• Call and return convention agnostic
Bad name, wasn't
really VMs
- 17. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Example C based IR
• The ubiquitous Hello World program…
#include <stdio.h>
!
int main() {
puts("Hello World")
}
@.str = private unnamed_addr constant [12 x i8] ⤦
c"Hello World00", align 1
!
define i32 @main() #0 {
%1 = call i32 @puts(i8* getelementptr inbounds
([12 x i8]* @.str, i32 0, i32 0))
ret i32 0
}
clang helloWorld.c -emit-llvm -c -S -o -
- 18. Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
@.str = private unnamed_addr constant [12 x i8] ⤦
c"Hello World00", align 1
!
define i32 @main() #0 {
%1 = call i32 @puts(i8* getelementptr inbounds
([12 x i8]* @.str, i32 0, i32 0))
ret i32 0
}
clang helloWorld.c -emit-assembly -S -o -
_main
pushq %rbp
movq %rsp, %rbp
leaq L_.str(%rip), %rdi
callq _puts
xorl %eax, %eax
popq %rbp
retq
.section __TEXT
L_.str: ## was @.str
.asciz "Hello World"
stack management
rdi = &L_.str
puts(rdi)
eax = 0
return(eax)
L_.str = "Hello World"
main function
- 19. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Advantages of IR
• LLVM IR can still be understood when compiled
• Allows for more accurate transformations
• Inlining across method/function calls
• Elimination of unused code paths
• Optimisation phases that are language agnostic
- 20. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Example Swift based IR
• The ubiquitous Hello World program…
println("Hello World")
@0 = private unnamed_addr constant [12 x i8] ⤦
c"Hello World00"
!
define i32 @main(i32, i8**) {
…
call void @_TFSs7printlnU__FQ_T_(⤦
%swift.opaque* %5, ⤦
%swift.type* getelementptr inbounds ⤦
(%swift.full_type* @_TMdSS, i64 0, i32 1))
ret i32 0
}
swiftc helloWorld.swift -emit-ir —o -
- 21. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Name Mangling
• Name Mangling is source → assembly identifiers
• C name mangling: main → _main
• C++ name mangling: main → __Z4mainiPPc
• __Z = C++ name
• 4 = 4 characters following for name (main)
• i = int
• PPc = pointer to pointer to char (i.e. char**)
- 22. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Swift Name Mangling
• With the Swift symbol _TFSs7printlnU__FQ_T_
• _T = Swift symbol
• F = function
• Ss = "Swift" (module, as in Swift.println)
• 7println = "println" (function name)
• U__ = single generic type argument, unbound
• F = function
• Q_ = generic argument
• T_ = empty tuple () (return type)
- 23. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Swift Name Mangling
• With the Swift symbol _TFSs7printlnU__FQ_T_
• _T = Swift symbol
• F = function
• Ss = "Swift" (module, as in Swift.println)
• 7println = "println" (function name)
• U__ = single generic type argument, unbound
• F = function
• Q_ = generic argument
• T_ = empty tuple () (return type)
$ xcrun swift-demangle _TFSs7printlnU__FQ_T_
_TFSs7printlnU__FQ_T_ ---> Swift.println <A>(A) -> ()
- 24. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Swift Intermediate Language
• Similar to IL, but with some Swift specifics
println("Hello World")
sil_stage canonical
!
import Builtin
import Swift
import SwiftShims
!
// top_level_code
sil private @top_level_code : $@thin () -> () {
bb0:
// function_ref Swift.println <A>(A) -> ()
%0 = function_ref @_TFSs7printlnU__FQ_T_ : ⤦
$@thin <τ_0_0> (@in τ_0_0) -> () // user: %9
swiftc helloWorld.swift -emit-sil —o -
- 25. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Swift vTables
• Method lookup in Swift is like C++ with vTable
class World { func hello() {…} }
sil_stage canonical
import Builtin; import Swift; import SwiftShims
sil private @top_level_code : $@thin () -> () {
// function_ref Swift.println <A>(A) -> ()
%0 = function_ref @_TFSs7printlnU__FQ_T_ : ⤦
$@thin <τ_0_0> (@in τ_0_0) -> () // user: %9
…
sil_vtable World {
#World.hello!1: _TFC4main5World5hellofS0_FT_T_
// main.World.hello (main.World)() -> ()
#World.init!initializer.1: _TFC4main5WorldcfMS0_FT_S0_
// main.World.init (main.World.Type)() -> main.World
}
swiftc helloWorld.swift -emit-sil —o -
- 26. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
SwiftObject and ObjC
• Swift objects can also be used in Objective-C
• Swift instance in memory has an isa pointer
• Objective-C can call Swift code with no changes
• Swift classes have @objc to use dynamic dispatch
• Reduces optimisations
• Automatically applied when using ObjC
• Protocols, Superclasses
- 27. Dr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Where is Swift going?
- 28. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Is Swift swift yet?
• Is Swift as fast as C?
• Wrong question
• Is Swift as fast, or faster than Objective-C?
• Can be as fast for Objective-C interoperability
• Can be faster for data/struct processing
• More optimisation possibilities in future
- 29. @alblueDr Alex Blewitt @alblue Swift Under the Hood ©Bandlem Ltd
Swift
• Being heavily developed – 3 releases in a year
• Provides a transitional mechanism from ObjC
• Existing libraries/frameworks will continue to work
• Can drop down to native calls when necessary
• Used as replacement language in LLDB
• Future of iOS development?
- 31. Watch the video with slide synchronization on
InfoQ.com!
http://www.infoq.com/presentations/swift-
llvm