Submit Search
Upload
Swiftとメソッドのアレコレ
•
11 likes
•
13,292 views
N
Nobuo Saito
Follow
2015-09-27 Hacker Tackleにて
Read less
Read more
Engineering
Report
Share
Report
Share
1 of 83
Download now
Download to read offline
Recommended
Standford 2015 week3: Objective-C Compatibility, Property List, Views
Standford 2015 week3: Objective-C Compatibility, Property List, Views
彼得潘 Pan
OpenGL ES 3.2 Reference Guide
OpenGL ES 3.2 Reference Guide
The Khronos Group Inc.
Sycl 1.2 Reference Card
Sycl 1.2 Reference Card
The Khronos Group Inc.
Variables, expressions, standard types
Variables, expressions, standard types
Rubizza
OpenCL 3.0 Reference Guide
OpenCL 3.0 Reference Guide
The Khronos Group Inc.
C# 6.0 Preview
C# 6.0 Preview
Fujio Kojima
OpenCL 2.0 Reference Card
OpenCL 2.0 Reference Card
The Khronos Group Inc.
OpenERP Technical Memento V0.7.3
OpenERP Technical Memento V0.7.3
Borni DHIFI
Recommended
Standford 2015 week3: Objective-C Compatibility, Property List, Views
Standford 2015 week3: Objective-C Compatibility, Property List, Views
彼得潘 Pan
OpenGL ES 3.2 Reference Guide
OpenGL ES 3.2 Reference Guide
The Khronos Group Inc.
Sycl 1.2 Reference Card
Sycl 1.2 Reference Card
The Khronos Group Inc.
Variables, expressions, standard types
Variables, expressions, standard types
Rubizza
OpenCL 3.0 Reference Guide
OpenCL 3.0 Reference Guide
The Khronos Group Inc.
C# 6.0 Preview
C# 6.0 Preview
Fujio Kojima
OpenCL 2.0 Reference Card
OpenCL 2.0 Reference Card
The Khronos Group Inc.
OpenERP Technical Memento V0.7.3
OpenERP Technical Memento V0.7.3
Borni DHIFI
Tools for Making Machine Learning more Reactive
Tools for Making Machine Learning more Reactive
Jeff Smith
Design patterns in javascript
Design patterns in javascript
Abimbola Idowu
OpenSL ES 1.1 Reference Card
OpenSL ES 1.1 Reference Card
The Khronos Group Inc.
VTU DSA Lab Manual
VTU DSA Lab Manual
AkhilaaReddy
OpenCL 2.2 Reference Guide
OpenCL 2.2 Reference Guide
The Khronos Group Inc.
SYCL 1.2.1 Reference Card
SYCL 1.2.1 Reference Card
The Khronos Group Inc.
Unit 3
Unit 3
GOWSIKRAJAP
Hexadite Real Life Django ORM
Hexadite Real Life Django ORM
Maxim Braitmaiere
5分で学ぶ差分更新とRxDataSources
5分で学ぶ差分更新とRxDataSources
Yuji Hato
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
ssuserd6b1fd
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
Visual Engineering
OpenCL 2.1 Reference Guide
OpenCL 2.1 Reference Guide
The Khronos Group Inc.
OpenERP Technical Memento
OpenERP Technical Memento
Odoo
Crafting beautiful software
Crafting beautiful software
Jorn Oomen
package org dev
package org dev
jaya lakshmi
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...
ssuserd6b1fd
Java script obfuscation
Java script obfuscation
n|u - The Open Security Community
Imugi: Compiler made with Python
Imugi: Compiler made with Python
Han Lee
Exceptional exceptions
Exceptional exceptions
Llewellyn Falco
Applying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing Speed
Pascal-Louis Perez
Data Structure in C (Lab Programs)
Data Structure in C (Lab Programs)
Saket Pathak
Objective-c Runtime
Objective-c Runtime
Pavel Albitsky
More Related Content
What's hot
Tools for Making Machine Learning more Reactive
Tools for Making Machine Learning more Reactive
Jeff Smith
Design patterns in javascript
Design patterns in javascript
Abimbola Idowu
OpenSL ES 1.1 Reference Card
OpenSL ES 1.1 Reference Card
The Khronos Group Inc.
VTU DSA Lab Manual
VTU DSA Lab Manual
AkhilaaReddy
OpenCL 2.2 Reference Guide
OpenCL 2.2 Reference Guide
The Khronos Group Inc.
SYCL 1.2.1 Reference Card
SYCL 1.2.1 Reference Card
The Khronos Group Inc.
Unit 3
Unit 3
GOWSIKRAJAP
Hexadite Real Life Django ORM
Hexadite Real Life Django ORM
Maxim Braitmaiere
5分で学ぶ差分更新とRxDataSources
5分で学ぶ差分更新とRxDataSources
Yuji Hato
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
ssuserd6b1fd
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
Visual Engineering
OpenCL 2.1 Reference Guide
OpenCL 2.1 Reference Guide
The Khronos Group Inc.
OpenERP Technical Memento
OpenERP Technical Memento
Odoo
Crafting beautiful software
Crafting beautiful software
Jorn Oomen
package org dev
package org dev
jaya lakshmi
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...
ssuserd6b1fd
Java script obfuscation
Java script obfuscation
n|u - The Open Security Community
Imugi: Compiler made with Python
Imugi: Compiler made with Python
Han Lee
Exceptional exceptions
Exceptional exceptions
Llewellyn Falco
What's hot
(19)
Tools for Making Machine Learning more Reactive
Tools for Making Machine Learning more Reactive
Design patterns in javascript
Design patterns in javascript
OpenSL ES 1.1 Reference Card
OpenSL ES 1.1 Reference Card
VTU DSA Lab Manual
VTU DSA Lab Manual
OpenCL 2.2 Reference Guide
OpenCL 2.2 Reference Guide
SYCL 1.2.1 Reference Card
SYCL 1.2.1 Reference Card
Unit 3
Unit 3
Hexadite Real Life Django ORM
Hexadite Real Life Django ORM
5分で学ぶ差分更新とRxDataSources
5分で学ぶ差分更新とRxDataSources
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
OpenCL 2.1 Reference Guide
OpenCL 2.1 Reference Guide
OpenERP Technical Memento
OpenERP Technical Memento
Crafting beautiful software
Crafting beautiful software
package org dev
package org dev
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...
Java script obfuscation
Java script obfuscation
Imugi: Compiler made with Python
Imugi: Compiler made with Python
Exceptional exceptions
Exceptional exceptions
Similar to Swiftとメソッドのアレコレ
Applying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing Speed
Pascal-Louis Perez
Data Structure in C (Lab Programs)
Data Structure in C (Lab Programs)
Saket Pathak
Objective-c Runtime
Objective-c Runtime
Pavel Albitsky
droidQuery: The Android port of jQuery
droidQuery: The Android port of jQuery
PhDBrown
Part II: LLVM Intermediate Representation
Part II: LLVM Intermediate Representation
Wei-Ren Chen
Chapter 7 functions (c)
Chapter 7 functions (c)
hhliu
Coding Ajax
Coding Ajax
Ted Husted
Swift internals
Swift internals
Jung Kim
Introduction to Spring MVC
Introduction to Spring MVC
Richard Paul
Live Updating Swift Code
Live Updating Swift Code
Bartosz Polaczyk
Coding Ajax
Coding Ajax
Ted Husted
Treinamento Qt básico - aula II
Treinamento Qt básico - aula II
Marcelo Barros de Almeida
Array
Array
Anil Dutt
Advance java
Advance java
Vivek Kumar Sinha
Awt components
Awt components
Balwinder Kumar
Models, controllers and views
Models, controllers and views
priestc
Unit 3
Unit 3
GOWSIKRAJAP
var, let in SIL
var, let in SIL
Yusuke Kita
Practical Model View Programming (Roadshow Version)
Practical Model View Programming (Roadshow Version)
Marius Bugge Monsen
Hidden Gems in Swift
Hidden Gems in Swift
Netguru
Similar to Swiftとメソッドのアレコレ
(20)
Applying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing Speed
Data Structure in C (Lab Programs)
Data Structure in C (Lab Programs)
Objective-c Runtime
Objective-c Runtime
droidQuery: The Android port of jQuery
droidQuery: The Android port of jQuery
Part II: LLVM Intermediate Representation
Part II: LLVM Intermediate Representation
Chapter 7 functions (c)
Chapter 7 functions (c)
Coding Ajax
Coding Ajax
Swift internals
Swift internals
Introduction to Spring MVC
Introduction to Spring MVC
Live Updating Swift Code
Live Updating Swift Code
Coding Ajax
Coding Ajax
Treinamento Qt básico - aula II
Treinamento Qt básico - aula II
Array
Array
Advance java
Advance java
Awt components
Awt components
Models, controllers and views
Models, controllers and views
Unit 3
Unit 3
var, let in SIL
var, let in SIL
Practical Model View Programming (Roadshow Version)
Practical Model View Programming (Roadshow Version)
Hidden Gems in Swift
Hidden Gems in Swift
Recently uploaded
CCS355 Neural Network & Deep Learning UNIT III notes and Question bank .pdf
CCS355 Neural Network & Deep Learning UNIT III notes and Question bank .pdf
Asst.prof M.Gokilavani
Design and analysis of solar grass cutter.pdf
Design and analysis of solar grass cutter.pdf
Tagore Institute of Engineering And Technology
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdf
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdf
Asst.prof M.Gokilavani
IVE Industry Focused Event - Defence Sector 2024
IVE Industry Focused Event - Defence Sector 2024
Mark Billinghurst
Sachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
Sachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
Dr.Costas Sachpazis
Concrete Mix Design - IS 10262-2019 - .pptx
Concrete Mix Design - IS 10262-2019 - .pptx
KartikeyaDwivedi3
Call Us ≽ 8377877756 ≼ Call Girls In Shastri Nagar (Delhi)
Call Us ≽ 8377877756 ≼ Call Girls In Shastri Nagar (Delhi)
dollysharma2066
Architect Hassan Khalil Portfolio for 2024
Architect Hassan Khalil Portfolio for 2024
hassan khalil
Introduction-To-Agricultural-Surveillance-Rover.pptx
Introduction-To-Agricultural-Surveillance-Rover.pptx
k795866
young call girls in Rajiv Chowk🔝 9953056974 🔝 Delhi escort Service
young call girls in Rajiv Chowk🔝 9953056974 🔝 Delhi escort Service
9953056974 Low Rate Call Girls In Saket, Delhi NCR
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
João Esperancinha
main PPT.pptx of girls hostel security using rfid
main PPT.pptx of girls hostel security using rfid
NikhilNagaraju
Gurgaon ✡️9711147426✨Call In girls Gurgaon Sector 51 escort service
Gurgaon ✡️9711147426✨Call In girls Gurgaon Sector 51 escort service
jennyeacort
An introduction to Semiconductor and its types.pptx
An introduction to Semiconductor and its types.pptx
Purva Nikam
TechTAC® CFD Report Summary: A Comparison of Two Types of Tubing Anchor Catchers
TechTAC® CFD Report Summary: A Comparison of Two Types of Tubing Anchor Catchers
sdickerson1
CCS355 Neural Networks & Deep Learning Unit 1 PDF notes with Question bank .pdf
CCS355 Neural Networks & Deep Learning Unit 1 PDF notes with Question bank .pdf
Asst.prof M.Gokilavani
Artificial-Intelligence-in-Electronics (K).pptx
Artificial-Intelligence-in-Electronics (K).pptx
britheesh05
Application of Residue Theorem to evaluate real integrations.pptx
Application of Residue Theorem to evaluate real integrations.pptx
959SahilShah
computer application and construction management
computer application and construction management
MariconPadriquez1
Exploring_Network_Security_with_JA3_by_Rakesh Seal.pptx
Exploring_Network_Security_with_JA3_by_Rakesh Seal.pptx
null - The Open Security Community
Recently uploaded
(20)
CCS355 Neural Network & Deep Learning UNIT III notes and Question bank .pdf
CCS355 Neural Network & Deep Learning UNIT III notes and Question bank .pdf
Design and analysis of solar grass cutter.pdf
Design and analysis of solar grass cutter.pdf
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdf
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdf
IVE Industry Focused Event - Defence Sector 2024
IVE Industry Focused Event - Defence Sector 2024
Sachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
Sachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
Concrete Mix Design - IS 10262-2019 - .pptx
Concrete Mix Design - IS 10262-2019 - .pptx
Call Us ≽ 8377877756 ≼ Call Girls In Shastri Nagar (Delhi)
Call Us ≽ 8377877756 ≼ Call Girls In Shastri Nagar (Delhi)
Architect Hassan Khalil Portfolio for 2024
Architect Hassan Khalil Portfolio for 2024
Introduction-To-Agricultural-Surveillance-Rover.pptx
Introduction-To-Agricultural-Surveillance-Rover.pptx
young call girls in Rajiv Chowk🔝 9953056974 🔝 Delhi escort Service
young call girls in Rajiv Chowk🔝 9953056974 🔝 Delhi escort Service
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
main PPT.pptx of girls hostel security using rfid
main PPT.pptx of girls hostel security using rfid
Gurgaon ✡️9711147426✨Call In girls Gurgaon Sector 51 escort service
Gurgaon ✡️9711147426✨Call In girls Gurgaon Sector 51 escort service
An introduction to Semiconductor and its types.pptx
An introduction to Semiconductor and its types.pptx
TechTAC® CFD Report Summary: A Comparison of Two Types of Tubing Anchor Catchers
TechTAC® CFD Report Summary: A Comparison of Two Types of Tubing Anchor Catchers
CCS355 Neural Networks & Deep Learning Unit 1 PDF notes with Question bank .pdf
CCS355 Neural Networks & Deep Learning Unit 1 PDF notes with Question bank .pdf
Artificial-Intelligence-in-Electronics (K).pptx
Artificial-Intelligence-in-Electronics (K).pptx
Application of Residue Theorem to evaluate real integrations.pptx
Application of Residue Theorem to evaluate real integrations.pptx
computer application and construction management
computer application and construction management
Exploring_Network_Security_with_JA3_by_Rakesh Seal.pptx
Exploring_Network_Security_with_JA3_by_Rakesh Seal.pptx
Swiftとメソッドのアレコレ
1.
Swiftとメソッドのアレコレ @tarunon 1
2.
自己紹介 @tarunon イカガチ勢 2015-09-26現在 ランク50 ウデマエS55 守備範囲:
Swift, Objective- C, JavaScript, Java, etc… 2
3.
Resume 3 復習Objective-C Swiftは何故速い? struct/enum アクセス修飾子 Any vs Generics Protocol
Extension optional func Closure
4.
復習Objective-C
5.
復習Objective-C Objective-Cは動的言語 objc_msgSend ランタイムAPI 5
6.
objc_msgSend 6 Class IMP void aFunction(id self,
SEL _cmd) { … } SEL 処理はCの関数と同等のIMPに存在 IMPへの参照とSelectorの組を持つ
7.
objc_msgSend 7 objc_msgSend Object SEL Arguments objc_msgSendが IMPを検索して実行する 高コスト!遅い!
8.
objc_msgSend 8 「クリティカルな部分はCで書く」 「C++」
9.
ランタイムAPI 9 クラスにメソッドを追加 クラスにプロパティを追加 Method Swizzling クラスを追加
10.
objc_msgSendの恩恵 10 クラスの継承 UIControl::addTarget:action:forControlEvents: @optionalなメソッド(Protocol) CoreData モデルを定義するためにObjective-Cランタイ ムを駆使
11.
Swiftは何故速い? ※LLVM中間コードが大量に出現します。ご注意下さい。
12.
Swiftは何故速い? 12 @interface A :
NSObject @property (nonatomic) NSString *str; @property (nonatomic) NSInteger integer; @end @implementation A - (void)function { } @end
13.
Swiftは何故速い? 13 clang -S -emit-llvm
source.m
14.
Swiftは何故速い? 14 @"OBJC_IVAR_$_A._str" = hidden
global i64 8, section "__DATA, __objc_ivar", align 8 @"OBJC_IVAR_$_A._integer" = hidden global i64 16, section "__DATA, __objc_ivar", align 8 @_objc_empty_cache = external global %struct._objc_cache @"OBJC_METACLASS_$_NSObject" = external global %struct._class_t @OBJC_CLASS_NAME_ = private global [2 x i8] c"A00", section "__TEXT,__objc_classname,cstring_literals", align 1 @"01l_OBJC_METACLASS_RO_$_A" = private global %struct._class_ro_t { i32 1, i32 40, i32 40, i8* null, i8* getelementptr inbounds ([2 x i8]* @OBJC_CLASS_NAME_, i32 0, i32 0), %struct.__method_list_t* null, %struct._objc_protocol_list* null, %struct._ivar_list_t* null, i8* null, %struct._prop_list_t* null }, section "__DATA, __objc_const", align 8 @"OBJC_METACLASS_$_A" = global %struct._class_t { %struct._class_t* @"OBJC_METACLASS_$_NSObject", %struct._class_t* @"OBJC_METACLASS_$_NSObject", %struct._objc_cache* @_objc_empty_cache, i8* (i8*, i8*)** null, %struct._class_ro_t* @"01l_OBJC_METACLASS_RO_$_A" }, section "__DATA, __objc_data", align 8 @"OBJC_CLASS_$_NSObject" = external global %struct._class_t @OBJC_METH_VAR_NAME_ = private global [9 x i8] c"function00", section "__TEXT,__objc_methname,cstring_literals", align 1 @OBJC_METH_VAR_TYPE_ = private global [8 x i8] c"v16@0:800", section "__TEXT,__objc_methtype,cstring_literals", align 1 @OBJC_METH_VAR_NAME_1 = private global [4 x i8] c"str00", section "__TEXT,__objc_methname,cstring_literals", align 1 @OBJC_METH_VAR_TYPE_2 = private global [8 x i8] c"@16@0:800", section "__TEXT,__objc_methtype,cstring_literals", align 1 @OBJC_METH_VAR_NAME_3 = private global [8 x i8] c"setStr:00", section "__TEXT,__objc_methname,cstring_literals", align 1 @OBJC_METH_VAR_TYPE_4 = private global [11 x i8] c"v24@0:8@1600", section "__TEXT,__objc_methtype,cstring_literals", align 1 @OBJC_METH_VAR_NAME_5 = private global [8 x i8] c"integer00", section "__TEXT,__objc_methname,cstring_literals", align 1 @OBJC_METH_VAR_TYPE_6 = private global [8 x i8] c"q16@0:800", section "__TEXT,__objc_methtype,cstring_literals", align 1 @OBJC_METH_VAR_NAME_7 = private global [12 x i8] c"setInteger:00", section "__TEXT,__objc_methname,cstring_literals", align 1 @OBJC_METH_VAR_TYPE_8 = private global [11 x i8] c"v24@0:8q1600", section "__TEXT,__objc_methtype,cstring_literals", align 1 @"01l_OBJC_$_INSTANCE_METHODS_A" = private global { i32, i32, [5 x %struct._objc_method] } { i32 24, i32 5, [5 x %struct._objc_method] [%struct._objc_method { i8* getelementptr inbounds ([9 x i8]* @OBJC_METH_VAR_NAME_, i32 0, i32 0), i8* getelementptr inbounds ([8 x i8]* @OBJC_METH_VAR_TYPE_, i32 0, i32 0), i8* bitcast (void (%0*, i8*)* @"01-[A function]" to i8*) }, %struct._objc_method { i8* getelementptr inbounds ([4 x i8]* @OBJC_METH_VAR_NAME_1, i32 0, i32 0), i8* getelementptr inbounds ([8 x i8]* @OBJC_METH_VAR_TYPE_2, i32 0, i32 0), i8* bitcast (%1* (%0*, i8*)* @"01-[A str]" to i8*) }, %struct._objc_method { i8* getelementptr inbounds ([8 x i8]* @OBJC_METH_VAR_NAME_3, i32 0, i32 0), i8* getelementptr inbounds ([11 x i8]* @OBJC_METH_VAR_TYPE_4, i32 0, i32 0), i8* bitcast (void (%0*, i8*, %1*)* @"01-[A setStr:]" to i8*) }, %struct._objc_method { i8* getelementptr inbounds ([8 x i8]* @OBJC_METH_VAR_NAME_5, i32 0, i32 0), i8* getelementptr inbounds ([8 x i8]* @OBJC_METH_VAR_TYPE_6, i32 0, i32 0), i8* bitcast (i64 (%0*, i8*)* @"01-[A integer]" to i8*) }, %struct._objc_method { i8* getelementptr inbounds ([12 x i8]* @OBJC_METH_VAR_NAME_7, i32 0, i32 0), i8* getelementptr inbounds ([11 x i8]* @OBJC_METH_VAR_TYPE_8, i32 0, i32 0), i8* bitcast (void (%0*, i8*, i64)* @"01-[A setInteger:]" to i8*) }] }, section "__DATA, __objc_const", align 8 @OBJC_METH_VAR_NAME_9 = private global [5 x i8] c"_str00", section "__TEXT,__objc_methname,cstring_literals", align 1 @OBJC_METH_VAR_TYPE_10 = private global [12 x i8] c"@22NSString2200", section "__TEXT,__objc_methtype,cstring_literals", align 1 @OBJC_METH_VAR_NAME_11 = private global [9 x i8] c"_integer00", section "__TEXT,__objc_methname,cstring_literals", align 1 @OBJC_METH_VAR_TYPE_12 = private global [2 x i8] c"q00", section "__TEXT,__objc_methtype,cstring_literals", align 1 @"01l_OBJC_$_INSTANCE_VARIABLES_A" = private global { i32, i32, [2 x %struct._ivar_t] } { i32 32, i32 2, [2 x %struct._ivar_t] [%struct._ivar_t { i64* @"OBJC_IVAR_$_A._str", i8* getelementptr inbounds ([5 x i8]* @OBJC_METH_VAR_NAME_9, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8]* @OBJC_METH_VAR_TYPE_10, i32 0, i32 0), i32 3, i32 8 }, %struct._ivar_t { i64* @"OBJC_IVAR_$_A._integer", i8* getelementptr inbounds ([9 x i8]* @OBJC_METH_VAR_NAME_11, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8]* @OBJC_METH_VAR_TYPE_12, i32 0, i32 0), i32 3, i32 8 }] }, section "__DATA, __objc_const", align 8 @OBJC_PROP_NAME_ATTR_ = private global [4 x i8] c"str00", section "__TEXT,__cstring,cstring_literals", align 1 @OBJC_PROP_NAME_ATTR_13 = private global [21 x i8] c"T@22NSString22,N,V_str00", section "__TEXT,__cstring,cstring_literals", align 1 @OBJC_PROP_NAME_ATTR_14 = private global [8 x i8] c"integer00", section "__TEXT,__cstring,cstring_literals", align 1 @OBJC_PROP_NAME_ATTR_15 = private global [15 x i8] c"Tq,N,V_integer00", section "__TEXT,__cstring,cstring_literals", align 1 @"01l_OBJC_$_PROP_LIST_A" = private global { i32, i32, [2 x %struct._prop_t] } { i32 16, i32 2, [2 x %struct._prop_t] [%struct._prop_t { i8* getelementptr inbounds ([4 x i8]* @OBJC_PROP_NAME_ATTR_, i32 0, i32 0), i8* getelementptr inbounds ([21 x i8]* @OBJC_PROP_NAME_ATTR_13, i32 0, i32 0) }, %struct._prop_t { i8* getelementptr inbounds ([8 x i8]* @OBJC_PROP_NAME_ATTR_14, i32 0, i32 0), i8* getelementptr inbounds ([15 x i8]* @OBJC_PROP_NAME_ATTR_15, i32 0, i32 0) }] }, section "__DATA, __objc_const", align 8 @"01l_OBJC_CLASS_RO_$_A" = private global %struct._class_ro_t { i32 0, i32 8, i32 24, i8* null, i8* getelementptr inbounds ([2 x i8]* @OBJC_CLASS_NAME_, i32 0, i32 0), %struct.__method_list_t* bitcast ({ i32, i32, [5 x %struct._objc_method] }* @"01l_OBJC_$_INSTANCE_METHODS_A" to %struct.__method_list_t*), %struct._objc_protocol_list* null, %struct._ivar_list_t* bitcast ({ i32, i32, [2 x %struct._ivar_t] }* @"01l_OBJC_$_INSTANCE_VARIABLES_A" to %struct._ivar_list_t*), i8* null, %struct._prop_list_t* bitcast ({ i32, i32, [2 x %struct._prop_t] }* @"01l_OBJC_$_PROP_LIST_A" to %struct._prop_list_t*) }, section "__DATA, __objc_const", align 8 @"OBJC_CLASS_$_A" = global %struct._class_t { %struct._class_t* @"OBJC_METACLASS_$_A", %struct._class_t* @"OBJC_CLASS_$_NSObject", %struct._objc_cache* @_objc_empty_cache, i8* (i8*, i8*)** null, %struct._class_ro_t* @"01l_OBJC_CLASS_RO_$_A" }, section "__DATA, __objc_data", align 8 @"OBJC_LABEL_CLASS_$" = private global [1 x i8*] [i8* bitcast (%struct._class_t* @"OBJC_CLASS_$_A" to i8*)], section "__DATA, __objc_classlist, regular, no_dead_strip", align 8
15.
Swiftは何故速い? 15 @"OBJC_IVAR_$_A._str" = hidden
global i64 8, section "__DATA, __objc_ivar", align 8 @"OBJC_IVAR_$_A._integer" = hidden global i64 16, section "__DATA, __objc_ivar", align 8 @_objc_empty_cache = external global %struct._objc_cache @"OBJC_METACLASS_$_NSObject" = external global %struct._class_t @OBJC_CLASS_NAME_ = private global [2 x i8] c"A00", section "__TEXT,__objc_classname,cstring_literals", align 1 @"01l_OBJC_METACLASS_RO_$_A" = private global %struct._class_ro_t { i32 1, i32 40, i32 40, i8* null, i8* getelementptr inbounds ([2 x i8]* @OBJC_CLASS_NAME_, i32 0, i32 0), %struct.__method_list_t* null, %struct._objc_protocol_list* null, %struct._ivar_list_t* null, i8* null, %struct._prop_list_t* null }, section "__DATA, __objc_const", align 8 @"OBJC_METACLASS_$_A" = global %struct._class_t { %struct._class_t* @"OBJC_METACLASS_$_NSObject", %struct._class_t* @"OBJC_METACLASS_$_NSObject", %struct._objc_cache* @_objc_empty_cache, i8* (i8*, i8*)** null, %struct._class_ro_t* @"01l_OBJC_METACLASS_RO_$_A" }, section "__DATA, __objc_data", align 8 @"OBJC_CLASS_$_NSObject" = external global %struct._class_t @OBJC_METH_VAR_NAME_ = private global [9 x i8] c"function00", section "__TEXT,__objc_methname,cstring_literals", align 1 @OBJC_METH_VAR_TYPE_ = private global [8 x i8] c"v16@0:800", section "__TEXT,__objc_methtype,cstring_literals", align 1 @OBJC_METH_VAR_NAME_1 = private global [4 x i8] c"str00", section "__TEXT,__objc_methname,cstring_literals", align 1 @OBJC_METH_VAR_TYPE_2 = private global [8 x i8] c"@16@0:800", section "__TEXT,__objc_methtype,cstring_literals", align 1 @OBJC_METH_VAR_NAME_3 = private global [8 x i8] c"setStr:00", section "__TEXT,__objc_methname,cstring_literals", align 1 @OBJC_METH_VAR_TYPE_4 = private global [11 x i8] c"v24@0:8@1600", section "__TEXT,__objc_methtype,cstring_literals", align 1 @OBJC_METH_VAR_NAME_5 = private global [8 x i8] c"integer00", section "__TEXT,__objc_methname,cstring_literals", align 1 @OBJC_METH_VAR_TYPE_6 = private global [8 x i8] c"q16@0:800", section "__TEXT,__objc_methtype,cstring_literals", align 1 @OBJC_METH_VAR_NAME_7 = private global [12 x i8] c"setInteger:00", section "__TEXT,__objc_methname,cstring_literals", align 1 @OBJC_METH_VAR_TYPE_8 = private global [11 x i8] c"v24@0:8q1600", section "__TEXT,__objc_methtype,cstring_literals", align 1 @"01l_OBJC_$_INSTANCE_METHODS_A" = private global { i32, i32, [5 x %struct._objc_method] } { i32 24, i32 5, [5 x %struct._objc_method] [%struct._objc_method { i8* getelementptr inbounds ([9 x i8]* @OBJC_METH_VAR_NAME_, i32 0, i32 0), i8* getelementptr inbounds ([8 x i8]* @OBJC_METH_VAR_TYPE_, i32 0, i32 0), i8* bitcast (void (%0*, i8*)* @"01-[A function]" to i8*) }, %struct._objc_method { i8* getelementptr inbounds ([4 x i8]* @OBJC_METH_VAR_NAME_1, i32 0, i32 0), i8* getelementptr inbounds ([8 x i8]* @OBJC_METH_VAR_TYPE_2, i32 0, i32 0), i8* bitcast (%1* (%0*, i8*)* @"01-[A str]" to i8*) }, %struct._objc_method { i8* getelementptr inbounds ([8 x i8]* @OBJC_METH_VAR_NAME_3, i32 0, i32 0), i8* getelementptr inbounds ([11 x i8]* @OBJC_METH_VAR_TYPE_4, i32 0, i32 0), i8* bitcast (void (%0*, i8*, %1*)* @"01-[A setStr:]" to i8*) }, %struct._objc_method { i8* getelementptr inbounds ([8 x i8]* @OBJC_METH_VAR_NAME_5, i32 0, i32 0), i8* getelementptr inbounds ([8 x i8]* @OBJC_METH_VAR_TYPE_6, i32 0, i32 0), i8* bitcast (i64 (%0*, i8*)* @"01-[A integer]" to i8*) }, %struct._objc_method { i8* getelementptr inbounds ([12 x i8]* @OBJC_METH_VAR_NAME_7, i32 0, i32 0), i8* getelementptr inbounds ([11 x i8]* @OBJC_METH_VAR_TYPE_8, i32 0, i32 0), i8* bitcast (void (%0*, i8*, i64)* @"01-[A setInteger:]" to i8*) }] }, section "__DATA, __objc_const", align 8 @OBJC_METH_VAR_NAME_9 = private global [5 x i8] c"_str00", section "__TEXT,__objc_methname,cstring_literals", align 1 @OBJC_METH_VAR_TYPE_10 = private global [12 x i8] c"@22NSString2200", section "__TEXT,__objc_methtype,cstring_literals", align 1 @OBJC_METH_VAR_NAME_11 = private global [9 x i8] c"_integer00", section "__TEXT,__objc_methname,cstring_literals", align 1 @OBJC_METH_VAR_TYPE_12 = private global [2 x i8] c"q00", section "__TEXT,__objc_methtype,cstring_literals", align 1 @"01l_OBJC_$_INSTANCE_VARIABLES_A" = private global { i32, i32, [2 x %struct._ivar_t] } { i32 32, i32 2, [2 x %struct._ivar_t] [%struct._ivar_t { i64* @"OBJC_IVAR_$_A._str", i8* getelementptr inbounds ([5 x i8]* @OBJC_METH_VAR_NAME_9, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8]* @OBJC_METH_VAR_TYPE_10, i32 0, i32 0), i32 3, i32 8 }, %struct._ivar_t { i64* @"OBJC_IVAR_$_A._integer", i8* getelementptr inbounds ([9 x i8]* @OBJC_METH_VAR_NAME_11, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8]* @OBJC_METH_VAR_TYPE_12, i32 0, i32 0), i32 3, i32 8 }] }, section "__DATA, __objc_const", align 8 @OBJC_PROP_NAME_ATTR_ = private global [4 x i8] c"str00", section "__TEXT,__cstring,cstring_literals", align 1 @OBJC_PROP_NAME_ATTR_13 = private global [21 x i8] c"T@22NSString22,N,V_str00", section "__TEXT,__cstring,cstring_literals", align 1 @OBJC_PROP_NAME_ATTR_14 = private global [8 x i8] c"integer00", section "__TEXT,__cstring,cstring_literals", align 1 @OBJC_PROP_NAME_ATTR_15 = private global [15 x i8] c"Tq,N,V_integer00", section "__TEXT,__cstring,cstring_literals", align 1 @"01l_OBJC_$_PROP_LIST_A" = private global { i32, i32, [2 x %struct._prop_t] } { i32 16, i32 2, [2 x %struct._prop_t] [%struct._prop_t { i8* getelementptr inbounds ([4 x i8]* @OBJC_PROP_NAME_ATTR_, i32 0, i32 0), i8* getelementptr inbounds ([21 x i8]* @OBJC_PROP_NAME_ATTR_13, i32 0, i32 0) }, %struct._prop_t { i8* getelementptr inbounds ([8 x i8]* @OBJC_PROP_NAME_ATTR_14, i32 0, i32 0), i8* getelementptr inbounds ([15 x i8]* @OBJC_PROP_NAME_ATTR_15, i32 0, i32 0) }] }, section "__DATA, __objc_const", align 8 @"01l_OBJC_CLASS_RO_$_A" = private global %struct._class_ro_t { i32 0, i32 8, i32 24, i8* null, i8* getelementptr inbounds ([2 x i8]* @OBJC_CLASS_NAME_, i32 0, i32 0), %struct.__method_list_t* bitcast ({ i32, i32, [5 x %struct._objc_method] }* @"01l_OBJC_$_INSTANCE_METHODS_A" to %struct.__method_list_t*), %struct._objc_protocol_list* null, %struct._ivar_list_t* bitcast ({ i32, i32, [2 x %struct._ivar_t] }* @"01l_OBJC_$_INSTANCE_VARIABLES_A" to %struct._ivar_list_t*), i8* null, %struct._prop_list_t* bitcast ({ i32, i32, [2 x %struct._prop_t] }* @"01l_OBJC_$_PROP_LIST_A" to %struct._prop_list_t*) }, section "__DATA, __objc_const", align 8 @"OBJC_CLASS_$_A" = global %struct._class_t { %struct._class_t* @"OBJC_METACLASS_$_A", %struct._class_t* @"OBJC_CLASS_$_NSObject", %struct._objc_cache* @_objc_empty_cache, i8* (i8*, i8*)** null, %struct._class_ro_t* @"01l_OBJC_CLASS_RO_$_A" }, section "__DATA, __objc_data", align 8 @"OBJC_LABEL_CLASS_$" = private global [1 x i8*] [i8* bitcast (%struct._class_t* @"OBJC_CLASS_$_A" to i8*)], section "__DATA, __objc_classlist, regular, no_dead_strip", align 8 Selectorの宣言
16.
Swiftは何故速い? 16 %a = alloca
%0*, align 8 %1 = load %struct._class_t** @"OBJC_CLASSLIST_REFERENCES_$_" %2 = load i8** @OBJC_SELECTOR_REFERENCES_, !invariant.load !6 %3 = bitcast %struct._class_t* %1 to i8* %4 = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* %3, i8* %2) %5 = bitcast i8* %4 to %0* store %0* %5, %0** %a, align 8 %6 = load %0** %a, align 8 %7 = load i8** @OBJC_SELECTOR_REFERENCES_17, !invariant.load !6 %8 = bitcast %0* %6 to i8* call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*)*)(i8* %8, i8* %7) ret i32 0
17.
Swiftは何故速い? 17 call void bitcast
(i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*)*)(i8* %8, i8* %7)
18.
Swiftは何故速い? 18 class A { var
str: String? var int: Int? func function() { } }
19.
Swiftは何故速い? 19 swiftc -emit-ir source.swift
> source.ll
20.
Swiftは何故速い? 20 @_TMnC6source1A = constant
{ i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 } { i64 0, i8* getelementptr inbounds ([11 x i8]* @4, i64 0, i64 0), i32 2, i32 17, i8* getelementptr inbounds ([9 x i8]* @5, i64 0, i64 0), %swift.type** (%swift.type*)* @get_field_types_A, %swift.type_pattern* null, i32 0, i32 0, i32 0 } @_TWoFC6source1Ag3strGSqSS_ = constant i64 88, align 8 @_TWoFC6source1As3strGSqSS_ = constant i64 96, align 8 @_TWoFC6source1Am3strGSqSS_ = constant i64 104, align 8 @_TWoFC6source1Ag3intGSqSi_ = constant i64 112, align 8 @_TWoFC6source1As3intGSqSi_ = constant i64 120, align 8 @_TWoFC6source1Am3intGSqSi_ = constant i64 128, align 8 @_TWoFC6source1A8functionfS0_FT_T_ = constant i64 136, align 8 @_TWoFC6source1ACfMS0_FT_S0_ = constant i64 144, align 8 @_TMLC6source1A = global %swift.type* null, align 8 @_TMdC6source1A = global { void (%C6source1A*)*, i8**, i64, %objc_class*, %swift.opaque*, %swift.opaque*, i64, i32, i32, i32, i16, i16, i32, i32, { i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 }*, void (%Sq*, %C6source1A*)*, void (%Sq*, %C6source1A*)*, { i8*, i64 } (i8*, [24 x i8]*, %C6source1A*)*, { i64, i1 } (%C6source1A*)*, void (i64, i1, %C6source1A*)*, { i8*, i64 } (i8*, [24 x i8]*, %C6source1A*)*, void (%C6source1A*)*, %C6source1A* (%C6source1A*)*, i64, i64 } { void (%C6source1A*)* @_TFC6source1AD, i8** @_TWVBo, i64 ptrtoint (%objc_class* @_TMmC6source1A to i64), %objc_class* @"OBJC_CLASS_$_SwiftObject", %swift.opaque* @_objc_empty_cache, %swift.opaque* @_objc_empty_vtable, i64 add (i64 ptrtoint ({ i32, i32, i32, i32, i8*, i8*, i8*, i8*, { i32, i32, [2 x { i64*, i8*, i8*, i32, i32 }] }*, i8*, i8* }* @_DATA__TtC6source1A to i64), i64 1), i32 3, i32 0, i32 57, i16 7, i16 0, i32 168, i32 16, { i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 }* @_TMnC6source1A, void (%Sq*, %C6source1A*)* @_TFC6source1Ag3strGSqSS_, void (%Sq*, %C6source1A*)* @_TFC6source1As3strGSqSS_, { i8*, i64 } (i8*, [24 x i8]*, %C6source1A*)* @_TFC6source1Am3strGSqSS_, { i64, i1 } (%C6source1A*)* @_TFC6source1Ag3intGSqSi_, void (i64, i1, %C6source1A*)* @_TFC6source1As3intGSqSi_, { i8*, i64 } (i8*, [24 x i8]*, %C6source1A*)* @_TFC6source1Am3intGSqSi_, void (%C6source1A*)* @_TFC6source1A8functionfS0_FT_T_, %C6source1A* (%C6source1A*)* @_TFC6source1AcfMS0_FT_S0_, i64 16, i64 48 }
21.
Swiftは何故速い? 21 @_TMnC6source1A = constant
{ i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 } { i64 0, i8* getelementptr inbounds ([11 x i8]* @4, i64 0, i64 0), i32 2, i32 17, i8* getelementptr inbounds ([9 x i8]* @5, i64 0, i64 0), %swift.type** (%swift.type*)* @get_field_types_A, %swift.type_pattern* null, i32 0, i32 0, i32 0 } @_TWoFC6source1Ag3strGSqSS_ = constant i64 88, align 8 @_TWoFC6source1As3strGSqSS_ = constant i64 96, align 8 @_TWoFC6source1Am3strGSqSS_ = constant i64 104, align 8 @_TWoFC6source1Ag3intGSqSi_ = constant i64 112, align 8 @_TWoFC6source1As3intGSqSi_ = constant i64 120, align 8 @_TWoFC6source1Am3intGSqSi_ = constant i64 128, align 8 @_TWoFC6source1A8functionfS0_FT_T_ = constant i64 136, align 8 @_TWoFC6source1ACfMS0_FT_S0_ = constant i64 144, align 8 @_TMLC6source1A = global %swift.type* null, align 8 @_TMdC6source1A = global { void (%C6source1A*)*, i8**, i64, %objc_class*, %swift.opaque*, %swift.opaque*, i64, i32, i32, i32, i16, i16, i32, i32, { i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 }*, void (%Sq*, %C6source1A*)*, void (%Sq*, %C6source1A*)*, { i8*, i64 } (i8*, [24 x i8]*, %C6source1A*)*, { i64, i1 } (%C6source1A*)*, void (i64, i1, %C6source1A*)*, { i8*, i64 } (i8*, [24 x i8]*, %C6source1A*)*, void (%C6source1A*)*, %C6source1A* (%C6source1A*)*, i64, i64 } { void (%C6source1A*)* @_TFC6source1AD, i8** @_TWVBo, i64 ptrtoint (%objc_class* @_TMmC6source1A to i64), %objc_class* @"OBJC_CLASS_$_SwiftObject", %swift.opaque* @_objc_empty_cache, %swift.opaque* @_objc_empty_vtable, i64 add (i64 ptrtoint ({ i32, i32, i32, i32, i8*, i8*, i8*, i8*, { i32, i32, [2 x { i64*, i8*, i8*, i32, i32 }] }*, i8*, i8* }* @_DATA__TtC6source1A to i64), i64 1), i32 3, i32 0, i32 57, i16 7, i16 0, i32 168, i32 16, { i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 }* @_TMnC6source1A, void (%Sq*, %C6source1A*)* @_TFC6source1Ag3strGSqSS_, void (%Sq*, %C6source1A*)* @_TFC6source1As3strGSqSS_, { i8*, i64 } (i8*, [24 x i8]*, %C6source1A*)* @_TFC6source1Am3strGSqSS_, { i64, i1 } (%C6source1A*)* @_TFC6source1Ag3intGSqSi_, void (i64, i1, %C6source1A*)* @_TFC6source1As3intGSqSi_, { i8*, i64 } (i8*, [24 x i8]*, %C6source1A*)* @_TFC6source1Am3intGSqSi_, void (%C6source1A*)* @_TFC6source1A8functionfS0_FT_T_, %C6source1A* (%C6source1A*)* @_TFC6source1AcfMS0_FT_S0_, i64 16, i64 48 } vtable
22.
Swiftは何故速い? 22 store i8* %2,
i8** getelementptr inbounds (%VSs20UnsafeMutablePointer* @_TZvOSs7Process11_unsafeArgvGVSs20UnsafeMutablePointerGS0_VSs4Int8__, i32 0, i32 0), align 8 %5 = call %swift.type* @_TMaC6source1A() #2 %6 = call %C6source1A* @_TFC6source1ACfMS0_FT_S0_(%swift.type* %5) store %C6source1A* %6, %C6source1A** @_Tv6source1aCS_1A, align 8 %7 = load %C6source1A** @_Tv6source1aCS_1A, align 8 %8 = bitcast %C6source1A* %7 to %swift.refcounted* call void @swift_retain_noresult(%swift.refcounted* %8) #3 %9 = bitcast %C6source1A* %7 to %swift.type** %.metadata = load %swift.type** %9, align 8 %10 = bitcast %swift.type* %.metadata to void (%C6source1A*)** %11 = getelementptr inbounds void (%C6source1A*)** %10, i64 9 %.metadata1 = load void (%C6source1A*)** %11, align 8, !invariant.load !29 %12 = bitcast void (%C6source1A*)* %.metadata1 to i8* %13 = bitcast i8* %12 to void (%C6source1A*)* call void %13(%C6source1A* %7) call void bitcast (void (%swift.refcounted*)* @swift_release to void (%C6source1A*)*)(%C6source1A* %7) #3 ret i32 0
23.
Swiftは何故速い? 23 store i8* %2,
i8** getelementptr inbounds (%VSs20UnsafeMutablePointer* @ %5 = call %swift.type* @_TMaC6source1A() #2 %6 = call %C6source1A* @_TFC6source1ACfMS0_FT_S0_(%swift.type* %5) store %C6source1A* %6, %C6source1A** @_Tv6source1aCS_1A, align 8 %7 = load %C6source1A** @_Tv6source1aCS_1A, align 8 %8 = bitcast %C6source1A* %7 to %swift.refcounted* call void @swift_retain_noresult(%swift.refcounted* %8) #3 %9 = bitcast %C6source1A* %7 to %swift.type** %.metadata = load %swift.type** %9, align 8 %10 = bitcast %swift.type* %.metadata to void (%C6source1A*)** %11 = getelementptr inbounds void (%C6source1A*)** %10, i64 9 %.metadata1 = load void (%C6source1A*)** %11, align 8, %12 = bitcast void (%C6source1A*)* %.metadata1 to i8* %13 = bitcast i8* %12 to void (%C6source1A*)* call void %13(%C6source1A* %7)
24.
Swiftは何故速い? 24 %11 = getelementptr
inbounds void (%C6source1A*)** %10, i64 9
25.
Swiftは何故速い? 25 class A: NSObject
{ var str: String? var int: Int? func function() { } }
26.
Swiftは何故速い? 26 @8 = private
unnamed_addr constant [14 x i8] c"_TtC6source1A00" @_METACLASS_DATA__TtC6source1A = private constant { i32, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8* } { i32 129, i32 40, i32 40, i32 0, i8* null, i8* getelementptr inbounds ([14 x i8]* @8, i64 0, i64 0), i8* null, i8* null, i8* null, i8* null, i8* null }, section "__DATA, __objc_const", align 8 @_INSTANCE_METHODS__TtC6source1A = private constant { i32, i32, [5 x { i8*, i8*, i8* }] } { i32 24, i32 5, [5 x { i8*, i8*, i8* }] [{ i8*, i8*, i8* } { i8* getelementptr inbounds ([4 x i8]* @"01L_selector_data(str)", i64 0, i64 0), i8* getelementptr inbounds ([8 x i8]* @3, i64 0, i64 0), i8* bitcast (%0* (%1*, i8*)* @_TToFC6source1Ag3strGSqSS_ to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([8 x i8]* @"01L_selector_data(setStr:)", i64 0, i64 0), i8* getelementptr inbounds ([11 x i8]* @4, i64 0, i64 0), i8* bitcast (void (%1*, i8*, %0*)* @_TToFC6source1As3strGSqSS_ to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([9 x i8]* @"01L_selector_data(function)", i64 0, i64 0), i8* getelementptr inbounds ([8 x i8]* @6, i64 0, i64 0), i8* bitcast (void (%1*, i8*)* @_TToFC6source1A8functionfS0_FT_T_ to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([5 x i8]* @"01L_selector_data(init)", i64 0, i64 0), i8* getelementptr inbounds ([8 x i8]* @3, i64 0, i64 0), i8* bitcast (%1* (%1*, i8*)* @_TToFC6source1AcfMS0_FT_S0_ to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([14 x i8]* @"01L_selector_data(.cxx_destruct)", i64 0, i64 0), i8* getelementptr inbounds ([3 x i8]* @7, i64 0, i64 0), i8* bitcast (void (%1*, i8*)* @_TToFC6source1AE to i8*) }] }, section "__DATA, __objc_const", align 8 @_IVARS__TtC6source1A = private constant { i32, i32, [2 x { i64*, i8*, i8*, i32, i32 }] } { i32 32, i32 2, [2 x { i64*, i8*, i8*, i32, i32 }] [{ i64*, i8*, i8*, i32, i32 } { i64* @_TWvdvC6source1A3strGSqSS_, i8* getelementptr inbounds ([4 x i8]* @0, i64 0, i64 0), i8* getelementptr inbounds ([1 x i8]* @1, i64 0, i64 0), i32 3, i32 25 }, { i64*, i8*, i8*, i32, i32 } { i64* @_TWvdvC6source1A3intGSqSi_, i8* getelementptr inbounds ([4 x i8]* @5, i64 0, i64 0), i8* getelementptr inbounds ([1 x i8]* @1, i64 0, i64 0), i32 3, i32 9 }] }, section "__DATA, __objc_const", align 8 @_PROPERTIES__TtC6source1A = private constant { i32, i32, [1 x { i8*, i8* }] } { i32 16, i32 1, [1 x { i8*, i8* }] [{ i8*, i8* } { i8* getelementptr inbounds ([4 x i8]* @0, i64 0, i64 0), i8* getelementptr inbounds ([22 x i8]* @2, i64 0, i64 0) }] }, section "__DATA, __objc_const", align 8 @_DATA__TtC6source1A = private constant { i32, i32, i32, i32, i8*, i8*, { i32, i32, [5 x { i8*, i8*, i8* }] }*, i8*, { i32, i32, [2 x { i64*, i8*, i8*, i32, i32 }] }*, i8*, { i32, i32, [1 x { i8*, i8* }] }* } { i32 388, i32 16, i32 57, i32 0, i8* null, i8* getelementptr inbounds ([14 x i8]* @8, i64 0, i64 0), { i32, i32, [5 x { i8*, i8*, i8* }] }* @_INSTANCE_METHODS__TtC6source1A, i8* null, { i32, i32, [2 x { i64*, i8*, i8*, i32, i32 }] }* @_IVARS__TtC6source1A, i8* null, { i32, i32, [1 x { i8*, i8* }] }* @_PROPERTIES__TtC6source1A }, section "__DATA, __objc_const", align 8 @9 = private unnamed_addr constant [11 x i8] c"C6source1A00" @10 = private unnamed_addr constant [9 x i8] c"str00int0000" @_TMnC6source1A = constant { i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 } { i64 0, i8* getelementptr inbounds ([11 x i8]* @9, i64 0, i64 0), i32 2, i32 17, i8* getelementptr inbounds ([9 x i8]* @10, i64 0, i64 0), %swift.type** (%swift.type*)* @get_field_types_A, %swift.type_pattern* null, i32 0, i32 0, i32 0 } @_TWoFC6source1Ag3strGSqSS_ = constant i64 88, align 8 @_TWoFC6source1As3strGSqSS_ = constant i64 96, align 8 @_TWoFC6source1Am3strGSqSS_ = constant i64 104, align 8 @_TWoFC6source1Ag3intGSqSi_ = constant i64 112, align 8 @_TWoFC6source1As3intGSqSi_ = constant i64 120, align 8 @_TWoFC6source1Am3intGSqSi_ = constant i64 128, align 8 @_TWoFC6source1A8functionfS0_FT_T_ = constant i64 136, align 8 @_TWoFC6source1ACfMS0_FT_S0_ = constant i64 144, align 8 @_TMLC6source1A = global %swift.type* null, align 8 @_TMdC6source1A = global { void (%C6source1A*)*, i8**, i64, %objc_class*, %swift.opaque*, %swift.opaque*, i64, i32, i32, i32, i16, i16, i32, i32, { i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 }*, void (%Sq.16*, %C6source1A*)*, void (%Sq.16*, %C6source1A*)*, { i8*, i64 } (i8*, [24 x i8]*, %C6source1A*)*, { i64, i1 } (%C6source1A*)*, void (i64, i1, %C6source1A*)*, { i8*, i64 } (i8*, [24 x i8]*, %C6source1A*)*, void (%C6source1A*)*, %C6source1A* (%C6source1A*)*, i64, i64 } { void (%C6source1A*)* @_TFC6source1AD, i8** @_TWVBO, i64 ptrtoint (%objc_class* @"OBJC_METACLASS_$__TtC6source1A" to i64), %objc_class* @"OBJC_CLASS_$_NSObject", %swift.opaque* @_objc_empty_cache, %swift.opaque* @_objc_empty_vtable, i64 add (i64 ptrtoint ({ i32, i32, i32, i32, i8*, i8*, { i32, i32, [5 x { i8*, i8*, i8* }] }*, i8*, { i32, i32, [2 x { i64*, i8*, i8*, i32, i32 }] }*, i8*, { i32, i32, [1 x { i8*, i8* }] }* }* @_DATA__TtC6source1A to i64), i64 1), i32 1, i32 0, i32 57, i16 7, i16 0, i32 168, i32 16, { i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 }* @_TMnC6source1A, void (%Sq.16*, %C6source1A*)* @_TFC6source1Ag3strGSqSS_, void (%Sq.16*, %C6source1A*)* @_TFC6source1As3strGSqSS_, { i8*, i64 } (i8*, [24 x i8]*, %C6source1A*)* @_TFC6source1Am3strGSqSS_, { i64, i1 } (%C6source1A*)* @_TFC6source1Ag3intGSqSi_, void (i64, i1, %C6source1A*)* @_TFC6source1As3intGSqSi_, { i8*, i64 } (i8*, [24 x i8]*, %C6source1A*)* @_TFC6source1Am3intGSqSi_, void (%C6source1A*)* @_TFC6source1A8functionfS0_FT_T_, %C6source1A* (%C6source1A*)* @_TFC6source1AcfMS0_FT_S0_, i64 16, i64 48 }, section "__DATA,__objc_data, regular, no_dead_strip"
27.
Swiftは何故速い? 27 @8 = private
unnamed_addr constant [14 x i8] c"_TtC6source1A00" @_METACLASS_DATA__TtC6source1A = private constant { i32, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8* } { i32 129, i32 40, i32 40, i32 0, i8* null, i8* getelementptr inbounds ([14 x i8]* @8, i64 0, i64 0), i8* null, i8* null, i8* null, i8* null, i8* null }, section "__DATA, __objc_const", align 8 @_INSTANCE_METHODS__TtC6source1A = private constant { i32, i32, [5 x { i8*, i8*, i8* }] } { i32 24, i32 5, [5 x { i8*, i8*, i8* }] [{ i8*, i8*, i8* } { i8* getelementptr inbounds ([4 x i8]* @"01L_selector_data(str)", i64 0, i64 0), i8* getelementptr inbounds ([8 x i8]* @3, i64 0, i64 0), i8* bitcast (%0* (%1*, i8*)* @_TToFC6source1Ag3strGSqSS_ to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([8 x i8]* @"01L_selector_data(setStr:)", i64 0, i64 0), i8* getelementptr inbounds ([11 x i8]* @4, i64 0, i64 0), i8* bitcast (void (%1*, i8*, %0*)* @_TToFC6source1As3strGSqSS_ to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([9 x i8]* @"01L_selector_data(function)", i64 0, i64 0), i8* getelementptr inbounds ([8 x i8]* @6, i64 0, i64 0), i8* bitcast (void (%1*, i8*)* @_TToFC6source1A8functionfS0_FT_T_ to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([5 x i8]* @"01L_selector_data(init)", i64 0, i64 0), i8* getelementptr inbounds ([8 x i8]* @3, i64 0, i64 0), i8* bitcast (%1* (%1*, i8*)* @_TToFC6source1AcfMS0_FT_S0_ to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([14 x i8]* @"01L_selector_data(.cxx_destruct)", i64 0, i64 0), i8* getelementptr inbounds ([3 x i8]* @7, i64 0, i64 0), i8* bitcast (void (%1*, i8*)* @_TToFC6source1AE to i8*) }] }, section "__DATA, __objc_const", align 8 @_IVARS__TtC6source1A = private constant { i32, i32, [2 x { i64*, i8*, i8*, i32, i32 }] } { i32 32, i32 2, [2 x { i64*, i8*, i8*, i32, i32 }] [{ i64*, i8*, i8*, i32, i32 } { i64* @_TWvdvC6source1A3strGSqSS_, i8* getelementptr inbounds ([4 x i8]* @0, i64 0, i64 0), i8* getelementptr inbounds ([1 x i8]* @1, i64 0, i64 0), i32 3, i32 25 }, { i64*, i8*, i8*, i32, i32 } { i64* @_TWvdvC6source1A3intGSqSi_, i8* getelementptr inbounds ([4 x i8]* @5, i64 0, i64 0), i8* getelementptr inbounds ([1 x i8]* @1, i64 0, i64 0), i32 3, i32 9 }] }, section "__DATA, __objc_const", align 8 @_PROPERTIES__TtC6source1A = private constant { i32, i32, [1 x { i8*, i8* }] } { i32 16, i32 1, [1 x { i8*, i8* }] [{ i8*, i8* } { i8* getelementptr inbounds ([4 x i8]* @0, i64 0, i64 0), i8* getelementptr inbounds ([22 x i8]* @2, i64 0, i64 0) }] }, section "__DATA, __objc_const", align 8 @_DATA__TtC6source1A = private constant { i32, i32, i32, i32, i8*, i8*, { i32, i32, [5 x { i8*, i8*, i8* }] }*, i8*, { i32, i32, [2 x { i64*, i8*, i8*, i32, i32 }] }*, i8*, { i32, i32, [1 x { i8*, i8* }] }* } { i32 388, i32 16, i32 57, i32 0, i8* null, i8* getelementptr inbounds ([14 x i8]* @8, i64 0, i64 0), { i32, i32, [5 x { i8*, i8*, i8* }] }* @_INSTANCE_METHODS__TtC6source1A, i8* null, { i32, i32, [2 x { i64*, i8*, i8*, i32, i32 }] }* @_IVARS__TtC6source1A, i8* null, { i32, i32, [1 x { i8*, i8* }] }* @_PROPERTIES__TtC6source1A }, section "__DATA, __objc_const", align 8 @9 = private unnamed_addr constant [11 x i8] c"C6source1A00" @10 = private unnamed_addr constant [9 x i8] c"str00int0000" @_TMnC6source1A = constant { i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 } { i64 0, i8* getelementptr inbounds ([11 x i8]* @9, i64 0, i64 0), i32 2, i32 17, i8* getelementptr inbounds ([9 x i8]* @10, i64 0, i64 0), %swift.type** (%swift.type*)* @get_field_types_A, %swift.type_pattern* null, i32 0, i32 0, i32 0 } @_TWoFC6source1Ag3strGSqSS_ = constant i64 88, align 8 @_TWoFC6source1As3strGSqSS_ = constant i64 96, align 8 @_TWoFC6source1Am3strGSqSS_ = constant i64 104, align 8 @_TWoFC6source1Ag3intGSqSi_ = constant i64 112, align 8 @_TWoFC6source1As3intGSqSi_ = constant i64 120, align 8 @_TWoFC6source1Am3intGSqSi_ = constant i64 128, align 8 @_TWoFC6source1A8functionfS0_FT_T_ = constant i64 136, align 8 @_TWoFC6source1ACfMS0_FT_S0_ = constant i64 144, align 8 @_TMLC6source1A = global %swift.type* null, align 8 @_TMdC6source1A = global { void (%C6source1A*)*, i8**, i64, %objc_class*, %swift.opaque*, %swift.opaque*, i64, i32, i32, i32, i16, i16, i32, i32, { i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 }*, void (%Sq.16*, %C6source1A*)*, void (%Sq.16*, %C6source1A*)*, { i8*, i64 } (i8*, [24 x i8]*, %C6source1A*)*, { i64, i1 } (%C6source1A*)*, void (i64, i1, %C6source1A*)*, { i8*, i64 } (i8*, [24 x i8]*, %C6source1A*)*, void (%C6source1A*)*, %C6source1A* (%C6source1A*)*, i64, i64 } { void (%C6source1A*)* @_TFC6source1AD, i8** @_TWVBO, i64 ptrtoint (%objc_class* @"OBJC_METACLASS_$__TtC6source1A" to i64), %objc_class* @"OBJC_CLASS_$_NSObject", %swift.opaque* @_objc_empty_cache, %swift.opaque* @_objc_empty_vtable, i64 add (i64 ptrtoint ({ i32, i32, i32, i32, i8*, i8*, { i32, i32, [5 x { i8*, i8*, i8* }] }*, i8*, { i32, i32, [2 x { i64*, i8*, i8*, i32, i32 }] }*, i8*, { i32, i32, [1 x { i8*, i8* }] }* }* @_DATA__TtC6source1A to i64), i64 1), i32 1, i32 0, i32 57, i16 7, i16 0, i32 168, i32 16, { i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 }* @_TMnC6source1A, void (%Sq.16*, %C6source1A*)* @_TFC6source1Ag3strGSqSS_, void (%Sq.16*, %C6source1A*)* @_TFC6source1As3strGSqSS_, { i8*, i64 } (i8*, [24 x i8]*, %C6source1A*)* @_TFC6source1Am3strGSqSS_, { i64, i1 } (%C6source1A*)* @_TFC6source1Ag3intGSqSi_, void (i64, i1, %C6source1A*)* @_TFC6source1As3intGSqSi_, { i8*, i64 } (i8*, [24 x i8]*, %C6source1A*)* @_TFC6source1Am3intGSqSi_, void (%C6source1A*)* @_TFC6source1A8functionfS0_FT_T_, %C6source1A* (%C6source1A*)* @_TFC6source1AcfMS0_FT_S0_, i64 16, i64 48 }, section "__DATA,__objc_data, regular, no_dead_strip" Selectorの宣言 vtable
28.
Swiftは何故速い? 28 store i8* %2,
i8** getelementptr inbounds (%VSs20UnsafeMutablePointer* @_TZvOSs7Process11_unsafeArgvGVSs20UnsafeMutablePointerGS0_VSs4Int8__, i32 0, i32 0), align 8 %5 = call %swift.type* @_TMaC6source1A() #2 %6 = call %C6source1A* @_TFC6source1ACfMS0_FT_S0_(%swift.type* %5) store %C6source1A* %6, %C6source1A** @_Tv6source1aCS_1A, align 8 %7 = load %C6source1A** @_Tv6source1aCS_1A, align 8 %8 = call %C6source1A* bitcast (%objc_object* (%objc_object*)* @objc_retain to %C6source1A* (%C6source1A*)*)(%C6source1A* %7) #3 %9 = bitcast %C6source1A* %7 to i64* %10 = load i64* %9, align 8 %11 = load i64* @swift_isaMask, align 8 %12 = and i64 %10, %11 %13 = inttoptr i64 %12 to %swift.type* %14 = bitcast %swift.type* %13 to void (%C6source1A*)** %15 = getelementptr inbounds void (%C6source1A*)** %14, i64 15 %16 = load void (%C6source1A*)** %15, align 8, !invariant.load !29 %17 = bitcast void (%C6source1A*)* %16 to i8* %18 = bitcast i8* %17 to void (%C6source1A*)* call void %18(%C6source1A* %7) call void bitcast (void (%objc_object*)* @objc_release to void (%C6source1A*)*)(%C6source1A* %7) #3 ret i32 0
29.
Swiftは何故速い? 29 store i8* %2,
i8** getelementptr inbounds (%VSs20UnsafeMutablePointer* @_TZvOSs7Process11_unsafeArgvGVSs20UnsafeMutablePointerGS0_VSs4Int8__, i32 0, i32 0), align 8 %5 = call %swift.type* @_TMaC6source1A() #2 %6 = call %C6source1A* @_TFC6source1ACfMS0_FT_S0_(%swift.type* %5) store %C6source1A* %6, %C6source1A** @_Tv6source1aCS_1A, align 8 %7 = load %C6source1A** @_Tv6source1aCS_1A, align 8 %8 = call %C6source1A* bitcast (%objc_object* (%objc_object*)* @objc_retain to %C6source1A* (%C6source1A*)*)(%C6source1A* %7) #3 %9 = bitcast %C6source1A* %7 to i64* %10 = load i64* %9, align 8 %11 = load i64* @swift_isaMask, align 8 %12 = and i64 %10, %11 %13 = inttoptr i64 %12 to %swift.type* %14 = bitcast %swift.type* %13 to void (%C6source1A*)** %15 = getelementptr inbounds void (%C6source1A*)** %14, i64 15 %16 = load void (%C6source1A*)** %15, align 8, !invariant.load !29 %17 = bitcast void (%C6source1A*)* %16 to i8* %18 = bitcast i8* %17 to void (%C6source1A*)* call void %18(%C6source1A* %7) call void bitcast (void (%objc_object*)* @objc_release to void (%C6source1A*)*)(%C6source1A* %7) #3 ret i32 0 objc_msgSendではない
30.
Swiftは何故速い? classメソッドの呼び出しが objc_msgSendからvtableに変更されパ フォーマンスが向上した NSObjectを継承すると、objc_msgSend が使用できる状態になるが、vtableも存 在し、vtableが優先的に使用される 30
31.
Swiftは何故速い? vtableを利用しているため、ランタ イムAPIを使ったテクニックの幾つか が使えなくなっていることに注意 Method SwizzlingはSwift製の クラスには無効 31
32.
struct/enum
33.
struct/enum 33 struct A { var
str: String? var int: Int? func function() { } }
34.
34 swiftc -emit-ir source.swift
> source.ll struct/enum
35.
struct/enum 35 @_Tv6source1aVS_1A = global
%V6source1A zeroinitializer, align 8 @_TZvOSs7Process5_argcVSs5Int32 = external global %VSs5Int32, align 4 @globalinit_33_1BDF70FFC18749BAB495A73B459ED2F0_token6 = external global i64, align 8 @_TZvOSs7Process11_unsafeArgvGVSs20UnsafeMutablePointerGS0_VSs4Int8__ = external global %VSs20UnsafeMutablePointer, align 8 @_TWVV6source1A = constant [20 x i8*] [i8* bitcast (void ([24 x i8]*, %swift.type*)* @_TwXXV6source1A to i8*), i8* bitcast (%swift.opaque* ([24 x i8]*, [24 x i8]*, %swift.type*)* @_TwCPV6source1A to i8*), i8* bitcast (%swift.opaque* ([24 x i8]*, %swift.type*)* @_TwprV6source1A to i8*), i8* bitcast (void ([24 x i8]*, %swift.type*)* @_TwdeV6source1A to i8*), i8* bitcast (void (%swift.opaque*, %swift.type*)* @_TwxxV6source1A to i8*), i8* bitcast (%swift.opaque* ([24 x i8]*, %swift.opaque*, %swift.type*)* @_TwCpV6source1A to i8*), i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @_TwcpV6source1A to i8*), i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @_TwcaV6source1A to i8*), i8* bitcast (%swift.opaque* ([24 x i8]*, %swift.opaque*, %swift.type*)* @_TwTkV6source1A to i8*), i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy41_8 to i8*), i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @_TwtaV6source1A to i8*), i8* bitcast (%swift.opaque* ([24 x i8]*, %swift.type*)* @_TwalV6source1A to i8*), i8* bitcast (i8* (i8**, i8**, %swift.type*)* @__swift_copy_outline_pointer to i8*), i8* bitcast (void (%swift.opaque*, i64, %swift.type*)* @_TwXxV6source1A to i8*), i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, i64, %swift.type*)* @_TwCcV6source1A to i8*), i8* bitcast (i8* (i8*, i8*, i64, %swift.type*)* @__swift_memmove_array48_8 to i8*), i8* bitcast (i8* (i8*, i8*, i64, %swift.type*)* @__swift_memmove_array48_8 to i8*), i8* inttoptr (i64 41 to i8*), i8* inttoptr (i64 196615 to i8*), i8* inttoptr (i64 48 to i8*)] @0 = private unnamed_addr constant [11 x i8] c"V6source1A00" @1 = private unnamed_addr constant [9 x i8] c"str00int0000" @_TMnV6source1A = constant { i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 } { i64 1, i8* getelementptr inbounds ([11 x i8]* @0, i64 0, i64 0), i32 2, i32 3, i8* getelementptr inbounds ([9 x i8]* @1, i64 0, i64 0), %swift.type** (%swift.type*)* @get_field_types_A, %swift.type_pattern* null, i32 0, i32 0, i32 0 } @_TMdV6source1A = constant { i8**, i64, { i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 }*, %swift.type*, i64, i64 } { i8** getelementptr inbounds ([20 x i8*]* @_TWVV6source1A, i32 0, i32 0), i64 1, { i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 }* @_TMnV6source1A, %swift.type* null, i64 0, i64 32 }
36.
struct/enum 36 @_Tv6source1aVS_1A = global
%V6source1A zeroinitializer, align 8 @_TZvOSs7Process5_argcVSs5Int32 = external global %VSs5Int32, align 4 @globalinit_33_1BDF70FFC18749BAB495A73B459ED2F0_token6 = external global i64, align 8 @_TZvOSs7Process11_unsafeArgvGVSs20UnsafeMutablePointerGS0_VSs4Int8__ = external global %VSs20UnsafeMutablePointer, align 8 @_TWVV6source1A = constant [20 x i8*] [i8* bitcast (void ([24 x i8]*, %swift.type*)* @_TwXXV6source1A to i8*), i8* bitcast (%swift.opaque* ([24 x i8]*, [24 x i8]*, %swift.type*)* @_TwCPV6source1A to i8*), i8* bitcast (%swift.opaque* ([24 x i8]*, %swift.type*)* @_TwprV6source1A to i8*), i8* bitcast (void ([24 x i8]*, %swift.type*)* @_TwdeV6source1A to i8*), i8* bitcast (void (%swift.opaque*, %swift.type*)* @_TwxxV6source1A to i8*), i8* bitcast (%swift.opaque* ([24 x i8]*, %swift.opaque*, %swift.type*)* @_TwCpV6source1A to i8*), i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @_TwcpV6source1A to i8*), i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @_TwcaV6source1A to i8*), i8* bitcast (%swift.opaque* ([24 x i8]*, %swift.opaque*, %swift.type*)* @_TwTkV6source1A to i8*), i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy41_8 to i8*), i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @_TwtaV6source1A to i8*), i8* bitcast (%swift.opaque* ([24 x i8]*, %swift.type*)* @_TwalV6source1A to i8*), i8* bitcast (i8* (i8**, i8**, %swift.type*)* @__swift_copy_outline_pointer to i8*), i8* bitcast (void (%swift.opaque*, i64, %swift.type*)* @_TwXxV6source1A to i8*), i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, i64, %swift.type*)* @_TwCcV6source1A to i8*), i8* bitcast (i8* (i8*, i8*, i64, %swift.type*)* @__swift_memmove_array48_8 to i8*), i8* bitcast (i8* (i8*, i8*, i64, %swift.type*)* @__swift_memmove_array48_8 to i8*), i8* inttoptr (i64 41 to i8*), i8* inttoptr (i64 196615 to i8*), i8* inttoptr (i64 48 to i8*)] @0 = private unnamed_addr constant [11 x i8] c"V6source1A00" @1 = private unnamed_addr constant [9 x i8] c"str00int0000" @_TMnV6source1A = constant { i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 } { i64 1, i8* getelementptr inbounds ([11 x i8]* @0, i64 0, i64 0), i32 2, i32 3, i8* getelementptr inbounds ([9 x i8]* @1, i64 0, i64 0), %swift.type** (%swift.type*)* @get_field_types_A, %swift.type_pattern* null, i32 0, i32 0, i32 0 } @_TMdV6source1A = constant { i8**, i64, { i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 }*, %swift.type*, i64, i64 } { i8** getelementptr inbounds ([20 x i8*]* @_TWVV6source1A, i32 0, i32 0), i64 1, { i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 }* @_TMnV6source1A, %swift.type* null, i64 0, i64 32 } functionの記述が存在しない
37.
struct/enum 37 define hidden void
@_TFV6source1A8functionfS0_FT_T_(%V6source1A* noalias nocapture dereferenceable(41)) #0 { entry: %.str = getelementptr inbounds %V6source1A* %0, i32 0, i32 0 %1 = bitcast %Sq* %.str to { i64, i64, i64 }* %2 = getelementptr inbounds { i64, i64, i64 }* %1, i32 0, i32 0 %3 = load i64* %2, align 8 %4 = getelementptr inbounds { i64, i64, i64 }* %1, i32 0, i32 1 %5 = load i64* %4, align 8 %6 = getelementptr inbounds { i64, i64, i64 }* %1, i32 0, i32 2 %7 = load i64* %6, align 8 %8 = getelementptr inbounds %Sq* %.str, i32 0, i32 1 %9 = bitcast [1 x i8]* %8 to i1* %10 = load i1* %9, align 8 %.int = getelementptr inbounds %V6source1A* %0, i32 0, i32 2 %11 = bitcast %Sq.17* %.int to i64* %12 = load i64* %11, align 8 %13 = getelementptr inbounds %Sq.17* %.int, i32 0, i32 1 %14 = bitcast [1 x i8]* %13 to i1* %15 = load i1* %14, align 8 ret void }
38.
struct/enum 38 %.str = getelementptr
inbounds %V6source1A* %2, i32 0, i32 0 %31 = bitcast %Sq* %.str to { i64, i64, i64 }* %32 = getelementptr inbounds { i64, i64, i64 }* %31, i32 0, i32 0 store i64 %21, i64* %32, align 8 %33 = getelementptr inbounds { i64, i64, i64 }* %31, i32 0, i32 1 store i64 %22, i64* %33, align 8 %34 = getelementptr inbounds { i64, i64, i64 }* %31, i32 0, i32 2 store i64 %23, i64* %34, align 8 %35 = getelementptr inbounds %Sq* %.str, i32 0, i32 1 %36 = bitcast [1 x i8]* %35 to i1* store i1 %24, i1* %36, align 8 %.int = getelementptr inbounds %V6source1A* %2, i32 0, i32 2 %37 = bitcast %Sq.17* %.int to i64* store i64 %25, i64* %37, align 8 %38 = getelementptr inbounds %Sq.17* %.int, i32 0, i32 1 %39 = bitcast [1 x i8]* %38 to i1* store i1 %26, i1* %39, align 8 call void @_TFV6source1A8functionfS0_FT_T_(%V6source1A* noalias nocapture dereferenceable(41) %2) br i1 %24, label %43, label %40
39.
struct/enum 39 %.str = getelementptr
inbounds %V6source1A* %2, i32 0, i32 0 %31 = bitcast %Sq* %.str to { i64, i64, i64 }* %32 = getelementptr inbounds { i64, i64, i64 }* %31, i32 0, i32 0 store i64 %21, i64* %32, align 8 %33 = getelementptr inbounds { i64, i64, i64 }* %31, i32 0, i32 1 store i64 %22, i64* %33, align 8 %34 = getelementptr inbounds { i64, i64, i64 }* %31, i32 0, i32 2 store i64 %23, i64* %34, align 8 %35 = getelementptr inbounds %Sq* %.str, i32 0, i32 1 %36 = bitcast [1 x i8]* %35 to i1* store i1 %24, i1* %36, align 8 %.int = getelementptr inbounds %V6source1A* %2, i32 0, i32 2 %37 = bitcast %Sq.17* %.int to i64* store i64 %25, i64* %37, align 8 %38 = getelementptr inbounds %Sq.17* %.int, i32 0, i32 1 %39 = bitcast [1 x i8]* %38 to i1* store i1 %26, i1* %39, align 8 call void @_TFV6source1A8functionfS0_FT_T_(%V6source1A* noalias nocapture dereferenceable(41) %2) br i1 %24, label %43, label %40 関数を直接実行している
40.
struct/enum 40 struct/enumのメソッドはただの関数への エイリアス selfを利用する際にコピーが発生しない vtableよりも高パフォーマンス struct/enumは値型であるため、事ある毎 にコピーのコストが発生する
41.
アクセス修飾子の話
42.
アクセス修飾子 Swiftのアクセス修飾子は3種類 public internal private classにはfinal修飾子もある classメソッドの実行方法が変化 42
43.
アクセス修飾子 Swiftのアクセス修飾子は3種類 public…フレームワーク外から参照可 internal…同一フレームワーク内から参照可 private…同一ファイル内から参照可 クラスにはfinal修飾子もある 43
44.
アクセス修飾子 44 class A: NSObject
{ var str: String? var int: Int? private func function() { print(self) } }
45.
アクセス修飾子 45 @_Tv6source1aCS_1A = global
%C6source1A* null, align 8 @_TZvOSs7Process5_argcVSs5Int32 = external global %VSs5Int32, align 4 @globalinit_33_1BDF70FFC18749BAB495A73B459ED2F0_token6 = external global i64, align 8 @_TZvOSs7Process11_unsafeArgvGVSs20UnsafeMutablePointerGS0_VSs4Int8__ = external global %VSs20UnsafeMutablePointer, align 8 @_swiftEmptyArrayStorage = external global %VSC23_SwiftEmptyArrayStorage, align 8 @_TWvdvC6source1A3strGSqSS_ = global i64 16, align 8 @"01L_selector_data(dealloc)" = internal constant [8 x i8] c"dealloc00", section "__TEXT,__objc_methname,cstring_literals", align 1 @"01L_selector(dealloc)" = internal global i8* getelementptr inbounds ([8 x i8]* @"01L_selector_data(dealloc)", i64 0, i64 0), section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip", align 8 @_TWvdvC6source1A3intGSqSi_ = global i64 48, align 8 @"01L_selector_data(init)" = internal constant [5 x i8] c"init00", section "__TEXT,__objc_methname,cstring_literals", align 1 @"01L_selector(init)" = internal global i8* getelementptr inbounds ([5 x i8]* @"01L_selector_data(init)", i64 0, i64 0), section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip", align 8 @"01L_selector_data(allocWithZone:)" = internal constant [15 x i8] c"allocWithZone:00", section "__TEXT,__objc_methname,cstring_literals", align 1 @"01L_selector(allocWithZone:)" = internal global i8* getelementptr inbounds ([15 x i8]* @"01L_selector_data(allocWithZone:)", i64 0, i64 0), section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip", align 8 @_TWVBO = external global i8* @"OBJC_METACLASS_$__TtC6source1A" = global %objc_class { %objc_class* @"OBJC_METACLASS_$_NSObject", %objc_class* @"OBJC_METACLASS_$_NSObject", %swift.opaque* @_objc_empty_cache, %swift.opaque* @_objc_empty_vtable, i64 ptrtoint ({ i32, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8* }* @_METACLASS_DATA__TtC6source1A to i64) } @"OBJC_CLASS_$_NSObject" = external global %objc_class @_objc_empty_cache = external global %swift.opaque @_objc_empty_vtable = external global %swift.opaque @0 = private unnamed_addr constant [4 x i8] c"str00" @1 = private unnamed_addr constant [1 x i8] zeroinitializer @2 = private unnamed_addr constant [22 x i8] c"T@22NSString22,N,C,Vstr00" @"01L_selector_data(str)" = internal constant [4 x i8] c"str00", section "__TEXT,__objc_methname,cstring_literals", align 1 @3 = private unnamed_addr constant [8 x i8] c"@16@0:800" @"01L_selector_data(setStr:)" = internal constant [8 x i8] c"setStr:00", section "__TEXT,__objc_methname,cstring_literals", align 1 @4 = private unnamed_addr constant [11 x i8] c"v24@0:8@1600" @5 = private unnamed_addr constant [4 x i8] c"int00" @"01L_selector_data(.cxx_destruct)" = internal constant [14 x i8] c".cxx_destruct00", section "__TEXT,__objc_methname,cstring_literals", align 1 @6 = private unnamed_addr constant [3 x i8] c"@?00" @"OBJC_METACLASS_$_NSObject" = external global %objc_class @7 = private unnamed_addr constant [14 x i8] c"_TtC6source1A00" @_METACLASS_DATA__TtC6source1A = private constant { i32, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8* } { i32 129, i32 40, i32 40, i32 0, i8* null, i8* getelementptr inbounds ([14 x i8]* @7, i64 0, i64 0), i8* null, i8* null, i8* null, i8* null, i8* null }, section "__DATA, __objc_const", align 8 @_INSTANCE_METHODS__TtC6source1A = private constant { i32, i32, [4 x { i8*, i8*, i8* }] } { i32 24, i32 4, [4 x { i8*, i8*, i8* }] [{ i8*, i8*, i8* } { i8* getelementptr inbounds ([4 x i8]* @"01L_selector_data(str)", i64 0, i64 0), i8* getelementptr inbounds ([8 x i8]* @3, i64 0, i64 0), i8* bitcast (%0* (%1*, i8*)* @_TToFC6source1Ag3strGSqSS_ to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([8 x i8]* @"01L_selector_data(setStr:)", i64 0, i64 0), i8* getelementptr inbounds ([11 x i8]* @4, i64 0, i64 0), i8* bitcast (void (%1*, i8*, %0*)* @_TToFC6source1As3strGSqSS_ to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([5 x i8]* @"01L_selector_data(init)", i64 0, i64 0), i8* getelementptr inbounds ([8 x i8]* @3, i64 0, i64 0), i8* bitcast (%1* (%1*, i8*)* @_TToFC6source1AcfMS0_FT_S0_ to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([14 x i8]* @"01L_selector_data(.cxx_destruct)", i64 0, i64 0), i8* getelementptr inbounds ([3 x i8]* @6, i64 0, i64 0), i8* bitcast (void (%1*, i8*)* @_TToFC6source1AE to i8*) }] }, section "__DATA, __objc_const", align 8 @_IVARS__TtC6source1A = private constant { i32, i32, [2 x { i64*, i8*, i8*, i32, i32 }] } { i32 32, i32 2, [2 x { i64*, i8*, i8*, i32, i32 }] [{ i64*, i8*, i8*, i32, i32 } { i64* @_TWvdvC6source1A3strGSqSS_, i8* getelementptr inbounds ([4 x i8]* @0, i64 0, i64 0), i8* getelementptr inbounds ([1 x i8]* @1, i64 0, i64 0), i32 3, i32 25 }, { i64*, i8*, i8*, i32, i32 } { i64* @_TWvdvC6source1A3intGSqSi_, i8* getelementptr inbounds ([4 x i8]* @5, i64 0, i64 0), i8* getelementptr inbounds ([1 x i8]* @1, i64 0, i64 0), i32 3, i32 9 }] }, section "__DATA, __objc_const", align 8 @_PROPERTIES__TtC6source1A = private constant { i32, i32, [1 x { i8*, i8* }] } { i32 16, i32 1, [1 x { i8*, i8* }] [{ i8*, i8* } { i8* getelementptr inbounds ([4 x i8]* @0, i64 0, i64 0), i8* getelementptr inbounds ([22 x i8]* @2, i64 0, i64 0) }] }, section "__DATA, __objc_const", align 8 @_DATA__TtC6source1A = private constant { i32, i32, i32, i32, i8*, i8*, { i32, i32, [4 x { i8*, i8*, i8* }] }*, i8*, { i32, i32, [2 x { i64*, i8*, i8*, i32, i32 }] }*, i8*, { i32, i32, [1 x { i8*, i8* }] }* } { i32 388, i32 16, i32 57, i32 0, i8* null, i8* getelementptr inbounds ([14 x i8]* @7, i64 0, i64 0), { i32, i32, [4 x { i8*, i8*, i8* }] }* @_INSTANCE_METHODS__TtC6source1A, i8* null, { i32, i32, [2 x { i64*, i8*, i8*, i32, i32 }] }* @_IVARS__TtC6source1A, i8* null, { i32, i32, [1 x { i8*, i8* }] }* @_PROPERTIES__TtC6source1A }, section "__DATA, __objc_const", align 8 @8 = private unnamed_addr constant [11 x i8] c"C6source1A00" @9 = private unnamed_addr constant [9 x i8] c"str00int0000" @_TMnC6source1A = constant { i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 } { i64 0, i8* getelementptr inbounds ([11 x i8]* @8, i64 0, i64 0), i32 2, i32 17, i8* getelementptr inbounds ([9 x i8]* @9, i64 0, i64 0), %swift.type** (%swift.type*)* @get_field_types_A, %swift.type_pattern* null, i32 0, i32 0, i32 0 } @_TWoFC6source1Ag3strGSqSS_ = constant i64 88, align 8 @_TWoFC6source1As3strGSqSS_ = constant i64 96, align 8 @_TWoFC6source1Am3strGSqSS_ = constant i64 104, align 8 @_TWoFC6source1Ag3intGSqSi_ = constant i64 112, align 8 @_TWoFC6source1As3intGSqSi_ = constant i64 120, align 8 @_TWoFC6source1Am3intGSqSi_ = constant i64 128, align 8 @_TWoFC6source1AP33_EDAF7582627E67611B2602683AEC23D58functionfS0_FT_T_ = hidden constant i64 136, align 8 @_TWoFC6source1ACfMS0_FT_S0_ = constant i64 144, align 8 @_TMLC6source1A = global %swift.type* null, align 8 @_TMdC6source1A = global { void (%C6source1A*)*, i8**, i64, %objc_class*, %swift.opaque*, %swift.opaque*, i64, i32, i32, i32, i16, i16, i32, i32, { i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 }*, void (%Sq.16*, %C6source1A*)*, void (%Sq.16*, %C6source1A*)*, { i8*, i64 } (i8*, [24 x i8]*, %C6source1A*)*, { i64, i1 } (%C6source1A*)*, void (i64, i1, %C6source1A*)*, { i8*, i64 } (i8*, [24 x i8]*, %C6source1A*)*, void (%C6source1A*)*, %C6source1A* (%C6source1A*)*, i64, i64 } { void (%C6source1A*)* @_TFC6source1AD, i8** @_TWVBO, i64 ptrtoint (%objc_class* @"OBJC_METACLASS_$__TtC6source1A" to i64), %objc_class* @"OBJC_CLASS_$_NSObject", %swift.opaque* @_objc_empty_cache, %swift.opaque* @_objc_empty_vtable, i64 add (i64 ptrtoint ({ i32, i32, i32, i32, i8*, i8*, { i32, i32, [4 x { i8*, i8*, i8* }] }*, i8*, { i32, i32, [2 x { i64*, i8*, i8*, i32, i32 }] }*, i8*, { i32, i32, [1 x { i8*, i8* }] }* }* @_DATA__TtC6source1A to i64), i64 1), i32 1, i32 0, i32 57, i16 7, i16 0, i32 168, i32 16, { i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 }* @_TMnC6source1A, void (%Sq.16*, %C6source1A*)* @_TFC6source1Ag3strGSqSS_, void (%Sq.16*, %C6source1A*)* @_TFC6source1As3strGSqSS_, { i8*, i64 } (i8*, [24 x i8]*, %C6source1A*)* @_TFC6source1Am3strGSqSS_, { i64, i1 } (%C6source1A*)* @_TFC6source1Ag3intGSqSi_, void (i64, i1, %C6source1A*)* @_TFC6source1As3intGSqSi_, { i8*, i64 } (i8*, [24 x i8]*, %C6source1A*)* @_TFC6source1Am3intGSqSi_, void (%C6source1A*)* @_TFC6source1AP33_EDAF7582627E67611B2602683AEC23D58functionfS0_FT_T_, %C6source1A* (%C6source1A*)* @_TFC6source1AcfMS0_FT_S0_, i64 16, i64 48 }, section "__DATA,__objc_data, regular, no_dead_strip" functionのSelectorが存在しない
46.
アクセス修飾子 46 @"01L_selector_data(dealloc)" = internal
constant [8 x i8] c"dealloc00", section "__TEXT,__objc_methname,cstring_literals", align 1 @"01L_selector(dealloc)" = internal global i8* getelementptr inbounds ([8 x i8]* @"01L_selector_data(dealloc)", i64 0, i64 0), section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip", align 8 @_TWvdvC6source1A3intGSqSi_ = global i64 48, align 8 @"01L_selector_data(init)" = internal constant [5 x i8] c"init00", section "__TEXT,__objc_methname,cstring_literals", align 1 @"01L_selector(init)" = internal global i8* getelementptr inbounds ([5 x i8]* @"01L_selector_data(init)", i64 0, i64 0), section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip", align 8 @"01L_selector_data(allocWithZone:)" = internal constant [15 x i8] c"allocWithZone:00", section "__TEXT,__objc_methname,cstring_literals", align 1 @"01L_selector(allocWithZone:)" = internal global i8* getelementptr inbounds ([15 x i8]* @"01L_selector_data(allocWithZone:)", i64 0, i64 0), section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip", align 8 @_TWVBO = external global i8* @"OBJC_METACLASS_$__TtC6source1A" = global %objc_class { %objc_class* @"OBJC_METACLASS_ $_NSObject", %objc_class* @"OBJC_METACLASS_$_NSObject", %swift.opaque* @_objc_empty_cache, %swift.opaque* @_objc_empty_vtable, i64 ptrtoint ({ i32, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8* }* @_METACLASS_DATA__TtC6source1A to i64) } @"OBJC_CLASS_$_NSObject" = external global %objc_class
47.
アクセス修飾子 47 store i8* %2,
i8** getelementptr inbounds (%VSs20UnsafeMutablePointer* @_TZvOSs7Process11_unsafeArgvGVSs20UnsafeMutablePointerGS0_VSs4Int8__, i32 0, i32 0), align 8 %5 = call %swift.type* @_TMaC6source1A() #3 %6 = call %C6source1A* @_TFC6source1ACfMS0_FT_S0_(%swift.type* %5) store %C6source1A* %6, %C6source1A** @_Tv6source1aCS_1A, align 8 %7 = load %C6source1A** @_Tv6source1aCS_1A, align 8 %8 = call %C6source1A* bitcast (%objc_object* (%objc_object*)* @objc_retain to %C6source1A* (%C6source1A*)*)(%C6source1A* %7) #4 call void @_TFC6source1AP33_EDAF7582627E67611B2602683AEC23D58functionfS0_FT_T_(%C6source1A* %7) call void bitcast (void (%objc_object*)* @objc_release to void (%C6source1A*)*) (%C6source1A* %7) #4 ret i32 0 関数を直接実行している
48.
アクセス修飾子 48 class B: A
{ override private func function() { } }
49.
アクセス修飾子 49 store i8* %2,
i8** getelementptr inbounds (%VSs20UnsafeMutablePointer* @_TZvOSs7Process11_unsafeArgvGVSs20UnsafeMutablePointerGS0_VSs4Int8__, i32 0, i32 0), align 8 %5 = call %swift.type* @_TMaC6source1A() #2 %6 = call %C6source1A* @_TFC6source1ACfMS0_FT_S0_(%swift.type* %5) store %C6source1A* %6, %C6source1A** @_Tv6source1aCS_1A, align 8 %7 = load %C6source1A** @_Tv6source1aCS_1A, align 8 %8 = call %C6source1A* bitcast (%objc_object* (%objc_object*)* @objc_retain to %C6source1A* (%C6source1A*)*)(%C6source1A* %7) #3 %9 = bitcast %C6source1A* %7 to i64* %10 = load i64* %9, align 8 %11 = load i64* @swift_isaMask, align 8 %12 = and i64 %10, %11 %13 = inttoptr i64 %12 to %swift.type* %14 = bitcast %swift.type* %13 to void (%C6source1A*)** %15 = getelementptr inbounds void (%C6source1A*)** %14, i64 15 %16 = load void (%C6source1A*)** %15, align 8, !invariant.load !29 %17 = bitcast void (%C6source1A*)* %16 to i8* %18 = bitcast i8* %17 to void (%C6source1A*)* call void %18(%C6source1A* %7) call void bitcast (void (%objc_object*)* @objc_release to void (%C6source1A*)*)(%C6source1A* %7) #3 %19 = call %swift.type* @_TMaC6source1B() #2 %20 = call %C6source1B* @_TFC6source1BCfMS0_FT_S0_(%swift.type* %19) store %C6source1B* %20, %C6source1B** @_Tv6source1bCS_1B, align 8 %21 = load %C6source1B** @_Tv6source1bCS_1B, align 8 %22 = call %C6source1B* bitcast (%objc_object* (%objc_object*)* @objc_retain to %C6source1B* (%C6source1B*)*)(%C6source1B* %21) #3 call void @_TFC6source1BP33_EDAF7582627E67611B2602683AEC23D58functionfS0_FT_T_(%C6source1B* %21) call void bitcast (void (%objc_object*)* @objc_release to void (%C6source1B*)*)(%C6source1B* %21) #3 ret i32 0 直接実行 vtable
50.
アクセス修飾子 private修飾子 終端のメソッドは直接呼び出し オーバーライドされたものはvtable selectorは存在しない (objc_msgSendできない) final修飾子 直接呼び出し selectorは存在しない (objc_msgSendできない) 50 selectorは存在します
51.
アクセス修飾子 privateやfinalのついたメソッドを addTarget:action:に渡すと死ぬ 隠蔽したい場合は? モジュール切ってinternalに しましょう 51
52.
Any vs Generics
53.
Any Swiftで定義された「なんでも代入可 能な型」 typealias protocol<> Objective-Cのid型はAnyObjectに 相当 53
54.
Any Optionalの値を格納することも可能だが… Any?型の値をAny型に格納することも可 能。 ネストしたOptionalを取り出すのは面倒。 予めAny?で宣言するが吉。 54
55.
Any 例えばString?型の値をAny型に格納した場合、 a as? Optional<Any>では取り出せない。 a
as? Optional<String>で取り出す必要があ る。 Any型の引数には、渡した変数が型ごと含ま れているため。暗黙のキャストは走っていな い。 55
56.
Any 56 define hidden void
@_TF6source8functionFP_T_(%"protocol<>"* noalias nocapture dereferenceable(32)) #0 { entry: %1 = getelementptr inbounds %"protocol<>"* %0, i32 0, i32 1 %.metadata = load %swift.type** %1, align 8 %2 = getelementptr inbounds %"protocol<>"* %0, i32 0, i32 0 %3 = bitcast %swift.type* %.metadata to i8*** %4 = getelementptr inbounds i8*** %3, i64 -1 %.metadata.valueWitnesses = load i8*** %4, align 8, !invariant.load ! 29, !dereferenceable !30 %5 = load i8** %.metadata.valueWitnesses, align 8, !invariant.load !29 %destroyBuffer = bitcast i8* %5 to void ([24 x i8]*, %swift.type*)* call void %destroyBuffer([24 x i8]* %2, %swift.type* %.metadata) #1 ret void }
57.
Any 57 define hidden void
@_TF6source8functionFP_T_(%"protocol<>"* noalias nocapture dereferenceable(32)) #0 { entry: %1 = getelementptr inbounds %"protocol<>"* %0, i32 0, i32 1 %.metadata = load %swift.type** %1, align 8 %2 = getelementptr inbounds %"protocol<>"* %0, i32 0, i32 0 %3 = bitcast %swift.type* %.metadata to i8*** %4 = getelementptr inbounds i8*** %3, i64 -1 %.metadata.valueWitnesses = load i8*** %4, align 8, !invariant.load ! 29, !dereferenceable !30 %5 = load i8** %.metadata.valueWitnesses, align 8, !invariant.load !29 %destroyBuffer = bitcast i8* %5 to void ([24 x i8]*, %swift.type*)* call void %destroyBuffer([24 x i8]* %2, %swift.type* %.metadata) #1 ret void } Any型
58.
Generics Generics引数は、型引数と曖昧な型 に分割されて渡される。 Genericsの制約が増えれば、型引数 も増える。 58
59.
Generics 59 define hidden void
@_TF6source8functionuRq_S_1P_Fq_T_(%swift.opaque* noalias nocapture, %swift.type* %A, i8** %A.P) #0 { entry: %A1 = alloca %swift.type*, align 8 store %swift.type* %A, %swift.type** %A1, align 8 %1 = bitcast %swift.type* %A to i8*** %2 = getelementptr inbounds i8*** %1, i64 -1 %A.valueWitnesses = load i8*** %2, align 8, !invariant.load !29, ! dereferenceable !30 %3 = getelementptr inbounds i8** %A.valueWitnesses, i32 4 %4 = load i8** %3, align 8, !invariant.load !29 %destroy = bitcast i8* %4 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* %0, %swift.type* %A) #1 ret void }
60.
Generics 60 define hidden void
@_TF6source8functionuRq_S_1P_Fq_T_(%swift.opaque* noalias nocapture, %swift.type* %A, i8** %A.P) #0 { entry: %A1 = alloca %swift.type*, align 8 store %swift.type* %A, %swift.type** %A1, align 8 %1 = bitcast %swift.type* %A to i8*** %2 = getelementptr inbounds i8*** %1, i64 -1 %A.valueWitnesses = load i8*** %2, align 8, !invariant.load !29, ! dereferenceable !30 %3 = getelementptr inbounds i8** %A.valueWitnesses, i32 4 %4 = load i8** %3, align 8, !invariant.load !29 %destroy = bitcast i8* %4 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* %0, %swift.type* %A) #1 ret void } 型引数
61.
Any vs Generics 特殊な要求が無いのであれば、 Genericsを使うべき とりあえずAnyやAnyObjectの引数 はGenericsにしてみよう 61
62.
Protocol Extension
63.
Protocol Extension 63 protocol P
{ } extension P { func function() { } } class A: NSObject, P { var str: String? var int: Int? }
64.
Protocol Extension 64 store i8*
%3, i8** getelementptr inbounds (%VSs20UnsafeMutablePointer* @_TZvOSs7Process11_unsafeArgvGVSs20UnsafeMutablePointerGS0_VSs4Int8__, i32 0, i32 0), align 8 %6 = call %swift.type* @_TMaC6source1A() #2 %7 = call %C6source1A* @_TFC6source1ACfMS0_FT_S0_(%swift.type* %6) store %C6source1A* %7, %C6source1A** @_Tv6source1aCS_1A, align 8 %8 = load %C6source1A** @_Tv6source1aCS_1A, align 8 %9 = call %C6source1A* bitcast (%objc_object* (%objc_object*)* @objc_retain to %C6source1A* (%C6source1A*)*)(%C6source1A* %8) #3 store %C6source1A* %8, %C6source1A** %2, align 8 %10 = bitcast %C6source1A** %2 to %swift.opaque* call void @_TFeRq_6source1P_S_S0_8functionuRq_S0__fq_FT_T_(%swift.type* %6, i8** getelementptr inbounds ([0 x i8*]* @_TWPC6source1AS_1PS_, i32 0, i32 0), %swift.opaque* noalias nocapture %10) %11 = load %C6source1A** %2, align 8 call void bitcast (void (%objc_object*)* @objc_release to void (%C6source1A*)*)(%C6source1A* %11) #3 ret i32 0
65.
Protocol Extension 65 call void @_TFeRq_6source1P_S_S0_8functionuRq_S0__fq_FT_T_(%swift.t ype*
%6, i8** getelementptr inbounds ([0 x i8*]* @_TWPC6source1AS_1PS_, i32 0, i32 0), %swift.opaque* noalias nocapture %10)
66.
が 型がProtocolだった場合、
67.
Protocol Extension 67 store i8*
%3, i8** getelementptr inbounds (%VSs20UnsafeMutablePointer* @_TZvOSs7Process11_unsafeArgvGVSs20UnsafeMutablePointerGS0_VSs4Int8__, i32 0, i32 0), align 8 %6 = call %swift.type* @_TMaC6source1A() #2 store %swift.type* %6, %swift.type** getelementptr inbounds (%P6source1P_* @_Tv6source1aPS_1P_, i32 0, i32 1), align 8 store i8** getelementptr inbounds ([1 x i8*]* @_TWPC6source1AS_1PS_, i32 0, i32 0), i8*** getelementptr inbounds (%P6source1P_* @_Tv6source1aPS_1P_, i32 0, i32 2), align 8 %7 = call %C6source1A* @_TFC6source1ACfMS0_FT_S0_(%swift.type* %6) store %C6source1A* %7, %C6source1A** bitcast (%P6source1P_* @_Tv6source1aPS_1P_ to %C6source1A**), align 8 %_Tv6source1aPS_1P_.metadata = load %swift.type** getelementptr inbounds (%P6source1P_* @_Tv6source1aPS_1P_, i32 0, i32 1), align 8 %8 = getelementptr inbounds %P6source1P_* %2, i32 0, i32 1 store %swift.type* %_Tv6source1aPS_1P_.metadata, %swift.type** %8, align 8 %9 = load i8*** getelementptr inbounds (%P6source1P_* @_Tv6source1aPS_1P_, i32 0, i32 2), align 8 %10 = getelementptr inbounds %P6source1P_* %2, i32 0, i32 2 store i8** %9, i8*** %10, align 8 %11 = getelementptr inbounds %P6source1P_* %2, i32 0, i32 0 %12 = bitcast %swift.type* %_Tv6source1aPS_1P_.metadata to i8*** %13 = getelementptr inbounds i8*** %12, i64 -1 %_Tv6source1aPS_1P_.metadata.valueWitnesses = load i8*** %13, align 8, !invariant.load !29, !dereferenceable !30 %14 = getelementptr inbounds i8** %_Tv6source1aPS_1P_.metadata.valueWitnesses, i32 1 %15 = load i8** %14, align 8, !invariant.load !29 %initializeBufferWithCopyOfBuffer = bitcast i8* %15 to %swift.opaque* ([24 x i8]*, [24 x i8]*, %swift.type*)* %16 = call %swift.opaque* %initializeBufferWithCopyOfBuffer([24 x i8]* noalias %11, [24 x i8]* getelementptr inbounds (%P6source1P_* @_Tv6source1aPS_1P_, i32 0, i32 0), %swift.type* %_Tv6source1aPS_1P_.metadata) #3 %17 = getelementptr inbounds %P6source1P_* %2, i32 0, i32 1 %.metadata = load %swift.type** %17, align 8 %18 = getelementptr inbounds %P6source1P_* %2, i32 0, i32 0 %19 = bitcast %swift.type* %.metadata to i8*** %20 = getelementptr inbounds i8*** %19, i64 -1 %.metadata.valueWitnesses = load i8*** %20, align 8, !invariant.load !29, !dereferenceable !30 %21 = getelementptr inbounds i8** %.metadata.valueWitnesses, i32 2 %22 = load i8** %21, align 8, !invariant.load !29 %projectBuffer = bitcast i8* %22 to %swift.opaque* ([24 x i8]*, %swift.type*)* %23 = call %swift.opaque* %projectBuffer([24 x i8]* %18, %swift.type* %.metadata) #3 %24 = getelementptr inbounds %P6source1P_* %2, i32 0, i32 2 %witness-table = load i8*** %24, align 8 store %swift.type* %.metadata, %swift.type** %.metadata1, align 8 %25 = load i8** %witness-table, align 8, !invariant.load !29 %26 = bitcast i8* %25 to void (%swift.opaque*, %swift.type*)* call void %26(%swift.opaque* noalias nocapture %23, %swift.type* %.metadata)
68.
Protocol Extension 68 store i8*
%3, i8** getelementptr inbounds (%VSs20UnsafeMutablePointer* @_TZvOSs7Process11_unsafeArgvGVSs20UnsafeMutablePointerGS0_VSs4Int8__, i32 0, i32 0), align 8 %6 = call %swift.type* @_TMaC6source1A() #2 store %swift.type* %6, %swift.type** getelementptr inbounds (%P6source1P_* @_Tv6source1aPS_1P_, i32 0, i32 1), align 8 store i8** getelementptr inbounds ([1 x i8*]* @_TWPC6source1AS_1PS_, i32 0, i32 0), i8*** getelementptr inbounds (%P6source1P_* @_Tv6source1aPS_1P_, i32 0, i32 2), align 8 %7 = call %C6source1A* @_TFC6source1ACfMS0_FT_S0_(%swift.type* %6) store %C6source1A* %7, %C6source1A** bitcast (%P6source1P_* @_Tv6source1aPS_1P_ to %C6source1A**), align 8 %_Tv6source1aPS_1P_.metadata = load %swift.type** getelementptr inbounds (%P6source1P_* @_Tv6source1aPS_1P_, i32 0, i32 1), align 8 %8 = getelementptr inbounds %P6source1P_* %2, i32 0, i32 1 store %swift.type* %_Tv6source1aPS_1P_.metadata, %swift.type** %8, align 8 %9 = load i8*** getelementptr inbounds (%P6source1P_* @_Tv6source1aPS_1P_, i32 0, i32 2), align 8 %10 = getelementptr inbounds %P6source1P_* %2, i32 0, i32 2 store i8** %9, i8*** %10, align 8 %11 = getelementptr inbounds %P6source1P_* %2, i32 0, i32 0 %12 = bitcast %swift.type* %_Tv6source1aPS_1P_.metadata to i8*** %13 = getelementptr inbounds i8*** %12, i64 -1 %_Tv6source1aPS_1P_.metadata.valueWitnesses = load i8*** %13, align 8, !invariant.load !29, !dereferenceable !30 %14 = getelementptr inbounds i8** %_Tv6source1aPS_1P_.metadata.valueWitnesses, i32 1 %15 = load i8** %14, align 8, !invariant.load !29 %initializeBufferWithCopyOfBuffer = bitcast i8* %15 to %swift.opaque* ([24 x i8]*, [24 x i8]*, %swift.type*)* %16 = call %swift.opaque* %initializeBufferWithCopyOfBuffer([24 x i8]* noalias %11, [24 x i8]* getelementptr inbounds (%P6source1P_* @_Tv6source1aPS_1P_, i32 0, i32 0), %swift.type* %_Tv6source1aPS_1P_.metadata) #3 %17 = getelementptr inbounds %P6source1P_* %2, i32 0, i32 1 %.metadata = load %swift.type** %17, align 8 %18 = getelementptr inbounds %P6source1P_* %2, i32 0, i32 0 %19 = bitcast %swift.type* %.metadata to i8*** %20 = getelementptr inbounds i8*** %19, i64 -1 %.metadata.valueWitnesses = load i8*** %20, align 8, !invariant.load !29, !dereferenceable !30 %21 = getelementptr inbounds i8** %.metadata.valueWitnesses, i32 2 %22 = load i8** %21, align 8, !invariant.load !29 %projectBuffer = bitcast i8* %22 to %swift.opaque* ([24 x i8]*, %swift.type*)* %23 = call %swift.opaque* %projectBuffer([24 x i8]* %18, %swift.type* %.metadata) #3 %24 = getelementptr inbounds %P6source1P_* %2, i32 0, i32 2 %witness-table = load i8*** %24, align 8 store %swift.type* %.metadata, %swift.type** %.metadata1, align 8 %25 = load i8** %witness-table, align 8, !invariant.load !29 %26 = bitcast i8* %25 to void (%swift.opaque*, %swift.type*)* call void %26(%swift.opaque* noalias nocapture %23, %swift.type* %.metadata) witness-tableを利用
69.
optional func
70.
optional func 70 @objc protocol
Delegate: NSObjectProtocol { optional func function() }
71.
71 swiftc -emit-ir source.swift
> source.ll struct/enum
72.
optional func できませんでした。。。 コンパイラが賢い? 同一ファイル内はチェックしてい るっぽい 72
73.
Closure
74.
Closure Swiftではメソッドへの参照を Closureとして利用することが可能 (2.0 ) 74
75.
Closure 75 class A: NSObject
{ var str: String? var int: Int? private func function() { print(self) } } var a = A() var m = a.function
76.
Closure 76 store i8* %2,
i8** getelementptr inbounds (%VSs20UnsafeMutablePointer* @_TZvOSs7Process11_unsafeArgvGVSs20UnsafeMutablePointerGS0_VSs4Int8__, i32 0, i32 0), align 8 %5 = call %swift.type* @_TMaC6source1A() #3 %6 = call %C6source1A* @_TFC6source1ACfMS0_FT_S0_(%swift.type* %5) store %C6source1A* %6, %C6source1A** @_Tv6source1aCS_1A, align 8 %7 = load %C6source1A** @_Tv6source1aCS_1A, align 8 %8 = call %C6source1A* bitcast (%objc_object* (%objc_object*)* @objc_retain to %C6source1A* (%C6source1A*)*)(%C6source1A* %7) #4 %9 = call { i8*, %swift.refcounted* } @_TFC6source1AP33_EDAF7582627E67611B2602683AEC23D58functionFS0_FT_T_(%C6source1A* %7) %10 = extractvalue { i8*, %swift.refcounted* } %9, 0 %11 = extractvalue { i8*, %swift.refcounted* } %9, 1 store i8* %10, i8** getelementptr inbounds (%swift.function* @_Tv6source1mFT_T_, i32 0, i32 0), align 8 store %swift.refcounted* %11, %swift.refcounted** getelementptr inbounds (%swift.function* @_Tv6source1mFT_T_, i32 0, i32 1), align 8 %12 = load i8** getelementptr inbounds (%swift.function* @_Tv6source1mFT_T_, i32 0, i32 0), align 8 %13 = load %swift.refcounted** getelementptr inbounds (%swift.function* @_Tv6source1mFT_T_, i32 0, i32 1), align 8 call void @swift_retain_noresult(%swift.refcounted* %13) #4 %14 = bitcast i8* %12 to void (%swift.refcounted*)* call void %14(%swift.refcounted* %13) ret i32 0
77.
Closure 77 store i8* %2,
i8** getelementptr inbounds (%VSs20UnsafeMutablePointer* @_TZvOSs7Process11_unsafeArgvGVSs20UnsafeMutablePointerGS0_VSs4Int8__, i32 0, i32 0), align 8 %5 = call %swift.type* @_TMaC6source1A() #3 %6 = call %C6source1A* @_TFC6source1ACfMS0_FT_S0_(%swift.type* %5) store %C6source1A* %6, %C6source1A** @_Tv6source1aCS_1A, align 8 %7 = load %C6source1A** @_Tv6source1aCS_1A, align 8 %8 = call %C6source1A* bitcast (%objc_object* (%objc_object*)* @objc_retain to %C6source1A* (%C6source1A*)*)(%C6source1A* %7) #4 %9 = call { i8*, %swift.refcounted* } @_TFC6source1AP33_EDAF7582627E67611B2602683AEC23D58functionFS0_FT_T_(%C6source1A* %7) %10 = extractvalue { i8*, %swift.refcounted* } %9, 0 %11 = extractvalue { i8*, %swift.refcounted* } %9, 1 store i8* %10, i8** getelementptr inbounds (%swift.function* @_Tv6source1mFT_T_, i32 0, i32 0), align 8 store %swift.refcounted* %11, %swift.refcounted** getelementptr inbounds (%swift.function* @_Tv6source1mFT_T_, i32 0, i32 1), align 8 %12 = load i8** getelementptr inbounds (%swift.function* @_Tv6source1mFT_T_, i32 0, i32 0), align 8 %13 = load %swift.refcounted** getelementptr inbounds (%swift.function* @_Tv6source1mFT_T_, i32 0, i32 1), align 8 call void @swift_retain_noresult(%swift.refcounted* %13) #4 %14 = bitcast i8* %12 to void (%swift.refcounted*)* call void %14(%swift.refcounted* %13) ret i32 0 Closureを生成してラッピング
78.
Swiftのこれから
79.
Swiftのこれから Objective-Cランタイムから切り離 される可能性 objc_msgSendを使わなくても、代 替可能な環境が出来つつある 79
80.
Swiftのこれから addTarget:action: クロージャで代替が十分可能 メソッドをクロージャとして渡せるよ うになった(実際はラップされている) ReferenceCountingの問題 80
81.
Swiftのこれから optional func Protocol Extensionにデフォルト 実装を書くことで代替可能に見え るが… ちょっと挙動がバグっぽい 81
82.
Swiftのこれから optional func Protocol Extensionにデフォルト 実装を書くことで代替可能に見え るが… 82
83.
まとめ Swift実際速い struct/enumはメソッドが直接実行なの で超速い private, final付けると直接実行になるの で超速い Objective-Cランタイムに依存しない方向へ 83
Download now