SlideShare ist ein Scribd-Unternehmen logo
1 von 83
Downloaden Sie, um offline zu lesen
Swiftとメソッドのアレコレ
@tarunon
1
自己紹介
@tarunon
イカガチ勢 2015-09-26現在
ランク50 ウデマエS55
守備範囲: Swift, Objective-
C, JavaScript, Java, etc…
2
Resume
3
復習Objective-C
Swiftは何故速い?
struct/enum
アクセス修飾子
Any vs Generics
Protocol Extension
optional func
Closure
復習Objective-C
復習Objective-C
Objective-Cは動的言語
objc_msgSend
ランタイムAPI
5
objc_msgSend
6
Class
IMP
void aFunction(id self, SEL _cmd) {
…
}
SEL
処理はCの関数と同等のIMPに存在
IMPへの参照とSelectorの組を持つ
objc_msgSend
7
objc_msgSend
Object
SEL
Arguments
objc_msgSendが

IMPを検索して実行する
高コスト!遅い!
objc_msgSend
8
「クリティカルな部分はCで書く」
「C++」
ランタイムAPI
9
クラスにメソッドを追加
クラスにプロパティを追加
Method Swizzling
クラスを追加
objc_msgSendの恩恵
10
クラスの継承
UIControl::addTarget:action:forControlEvents:
@optionalなメソッド(Protocol)
CoreData
モデルを定義するためにObjective-Cランタイ
ムを駆使
Swiftは何故速い?
※LLVM中間コードが大量に出現します。ご注意下さい。
Swiftは何故速い?
12
@interface A : NSObject
@property (nonatomic) NSString *str;
@property (nonatomic) NSInteger integer;
@end
@implementation A
- (void)function
{
}
@end
Swiftは何故速い?
13
clang -S -emit-llvm source.m
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
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の宣言
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
Swiftは何故速い?
17
call void bitcast (i8* (i8*, i8*, ...)*
@objc_msgSend to void (i8*, i8*)*)(i8*
%8, i8* %7)
Swiftは何故速い?
18
class A {
var str: String?
var int: Int?
func function() {
}
}
Swiftは何故速い?
19
swiftc -emit-ir source.swift > source.ll
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 }
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
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
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)
Swiftは何故速い?
24
%11 = getelementptr inbounds void
(%C6source1A*)** %10, i64 9
Swiftは何故速い?
25
class A: NSObject {
var str: String?
var int: Int?
func function() {
}
}
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"
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
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
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ではない
Swiftは何故速い?
classメソッドの呼び出しが
objc_msgSendからvtableに変更されパ
フォーマンスが向上した
NSObjectを継承すると、objc_msgSend
が使用できる状態になるが、vtableも存
在し、vtableが優先的に使用される
30
Swiftは何故速い?
vtableを利用しているため、ランタ
イムAPIを使ったテクニックの幾つか
が使えなくなっていることに注意
Method SwizzlingはSwift製の

クラスには無効
31
struct/enum
struct/enum
33
struct A {
var str: String?
var int: Int?
func function() {
}
}
34
swiftc -emit-ir source.swift > source.ll
struct/enum
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 }
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の記述が存在しない
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
}
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
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
関数を直接実行している
struct/enum
40
struct/enumのメソッドはただの関数への
エイリアス
selfを利用する際にコピーが発生しない
vtableよりも高パフォーマンス
struct/enumは値型であるため、事ある毎
にコピーのコストが発生する
アクセス修飾子の話
アクセス修飾子
Swiftのアクセス修飾子は3種類
public
internal
private
classにはfinal修飾子もある
classメソッドの実行方法が変化
42
アクセス修飾子
Swiftのアクセス修飾子は3種類
public…フレームワーク外から参照可
internal…同一フレームワーク内から参照可
private…同一ファイル内から参照可
クラスにはfinal修飾子もある
43
アクセス修飾子
44
class A: NSObject {
var str: String?
var int: Int?
private func function() {
print(self)
}
}
アクセス修飾子
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
@"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
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
class B: A {
override private func function() {
}
}
アクセス修飾子
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
アクセス修飾子
private修飾子
終端のメソッドは直接呼び出し
オーバーライドされたものはvtable
selectorは存在しない (objc_msgSendできない)
final修飾子
直接呼び出し
selectorは存在しない (objc_msgSendできない)
50
selectorは存在します
アクセス修飾子
privateやfinalのついたメソッドを
addTarget:action:に渡すと死ぬ
隠蔽したい場合は?
モジュール切ってinternalに

 しましょう
51
Any vs Generics
Any
Swiftで定義された「なんでも代入可
能な型」
typealias protocol<>
Objective-Cのid型はAnyObjectに
相当
53
Any
Optionalの値を格納することも可能だが…
Any?型の値をAny型に格納することも可
能。
ネストしたOptionalを取り出すのは面倒。
予めAny?で宣言するが吉。
54
Any
例えばString?型の値をAny型に格納した場合、
a as? Optional<Any>では取り出せない。

a as? Optional<String>で取り出す必要があ
る。
Any型の引数には、渡した変数が型ごと含ま
れているため。暗黙のキャストは走っていな
い。
55
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
}
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型
Generics
Generics引数は、型引数と曖昧な型
に分割されて渡される。
Genericsの制約が増えれば、型引数
も増える。
58
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
}
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
}
型引数 
Any vs Generics
特殊な要求が無いのであれば、
Genericsを使うべき
とりあえずAnyやAnyObjectの引数
はGenericsにしてみよう
61
Protocol Extension
Protocol Extension
63
protocol P {
}
extension P {
func function() {
}
}
class A: NSObject, P {
var str: String?
var int: Int?
}
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
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)
が
型がProtocolだった場合、
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)
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を利用
optional func
optional func
70
@objc protocol Delegate: NSObjectProtocol {
optional func function()
}
71
swiftc -emit-ir source.swift > source.ll
struct/enum
optional func
できませんでした。。。
コンパイラが賢い?
同一ファイル内はチェックしてい
るっぽい
72
Closure
Closure
Swiftではメソッドへの参照を
Closureとして利用することが可能
(2.0 )
74
Closure
75
class A: NSObject {
var str: String?
var int: Int?
private func function() {
print(self)
}
}
var a = A()
var m = a.function
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
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を生成してラッピング
Swiftのこれから
Swiftのこれから
Objective-Cランタイムから切り離
される可能性
objc_msgSendを使わなくても、代
替可能な環境が出来つつある
79
Swiftのこれから
addTarget:action:
クロージャで代替が十分可能
メソッドをクロージャとして渡せるよ
うになった(実際はラップされている)
ReferenceCountingの問題
80
Swiftのこれから
optional func
Protocol Extensionにデフォルト
実装を書くことで代替可能に見え
るが…
ちょっと挙動がバグっぽい
81
Swiftのこれから
optional func
Protocol Extensionにデフォルト
実装を書くことで代替可能に見え
るが…
82
まとめ
Swift実際速い
struct/enumはメソッドが直接実行なの
で超速い
private, final付けると直接実行になるの
で超速い
Objective-Cランタイムに依存しない方向へ
83

Weitere ähnliche Inhalte

Was ist angesagt?

Tools for Making Machine Learning more Reactive
Tools for Making Machine Learning more ReactiveTools for Making Machine Learning more Reactive
Tools for Making Machine Learning more ReactiveJeff Smith
 
Design patterns in javascript
Design patterns in javascriptDesign patterns in javascript
Design patterns in javascriptAbimbola Idowu
 
VTU DSA Lab Manual
VTU DSA Lab ManualVTU DSA Lab Manual
VTU DSA Lab ManualAkhilaaReddy
 
Hexadite Real Life Django ORM
Hexadite Real Life Django ORMHexadite Real Life Django ORM
Hexadite Real Life Django ORMMaxim Braitmaiere
 
5分で学ぶ差分更新とRxDataSources
5分で学ぶ差分更新とRxDataSources5分で学ぶ差分更新とRxDataSources
5分で学ぶ差分更新とRxDataSourcesYuji 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 ...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 JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptVisual Engineering
 
OpenERP Technical Memento
OpenERP Technical MementoOpenERP Technical Memento
OpenERP Technical MementoOdoo
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful softwareJorn Oomen
 
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...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
 
Imugi: Compiler made with Python
Imugi: Compiler made with PythonImugi: Compiler made with Python
Imugi: Compiler made with PythonHan Lee
 

Was ist angesagt? (19)

Tools for Making Machine Learning more Reactive
Tools for Making Machine Learning more ReactiveTools for Making Machine Learning more Reactive
Tools for Making Machine Learning more Reactive
 
Design patterns in javascript
Design patterns in javascriptDesign patterns in javascript
Design patterns in javascript
 
OpenSL ES 1.1 Reference Card
OpenSL ES 1.1 Reference CardOpenSL ES 1.1 Reference Card
OpenSL ES 1.1 Reference Card
 
VTU DSA Lab Manual
VTU DSA Lab ManualVTU DSA Lab Manual
VTU DSA Lab Manual
 
OpenCL 2.2 Reference Guide
OpenCL 2.2 Reference GuideOpenCL 2.2 Reference Guide
OpenCL 2.2 Reference Guide
 
SYCL 1.2.1 Reference Card
SYCL 1.2.1 Reference CardSYCL 1.2.1 Reference Card
SYCL 1.2.1 Reference Card
 
Unit 3
Unit 3 Unit 3
Unit 3
 
Hexadite Real Life Django ORM
Hexadite Real Life Django ORMHexadite Real Life Django ORM
Hexadite Real Life Django ORM
 
5分で学ぶ差分更新とRxDataSources
5分で学ぶ差分更新とRxDataSources5分で学ぶ差分更新と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 ...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 JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
 
OpenCL 2.1 Reference Guide
OpenCL 2.1 Reference GuideOpenCL 2.1 Reference Guide
OpenCL 2.1 Reference Guide
 
OpenERP Technical Memento
OpenERP Technical MementoOpenERP Technical Memento
OpenERP Technical Memento
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful software
 
package org dev
package org devpackage 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...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 obfuscationJava script obfuscation
Java script obfuscation
 
Imugi: Compiler made with Python
Imugi: Compiler made with PythonImugi: Compiler made with Python
Imugi: Compiler made with Python
 
Exceptional exceptions
Exceptional exceptionsExceptional exceptions
Exceptional exceptions
 

Ähnlich wie Swiftとメソッドのアレコレ

Applying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedApplying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedPascal-Louis Perez
 
Data Structure in C (Lab Programs)
Data Structure in C (Lab Programs)Data Structure in C (Lab Programs)
Data Structure in C (Lab Programs)Saket Pathak
 
droidQuery: The Android port of jQuery
droidQuery: The Android port of jQuerydroidQuery: The Android port of jQuery
droidQuery: The Android port of jQueryPhDBrown
 
Part II: LLVM Intermediate Representation
Part II: LLVM Intermediate RepresentationPart II: LLVM Intermediate Representation
Part II: LLVM Intermediate RepresentationWei-Ren Chen
 
Chapter 7 functions (c)
Chapter 7 functions (c)Chapter 7 functions (c)
Chapter 7 functions (c)hhliu
 
Swift internals
Swift internalsSwift internals
Swift internalsJung Kim
 
Introduction to Spring MVC
Introduction to Spring MVCIntroduction to Spring MVC
Introduction to Spring MVCRichard Paul
 
Models, controllers and views
Models, controllers and viewsModels, controllers and views
Models, controllers and viewspriestc
 
Practical Model View Programming (Roadshow Version)
Practical Model View Programming (Roadshow Version)Practical Model View Programming (Roadshow Version)
Practical Model View Programming (Roadshow Version)Marius Bugge Monsen
 
Hidden Gems in Swift
Hidden Gems in SwiftHidden Gems in Swift
Hidden Gems in SwiftNetguru
 

Ähnlich wie Swiftとメソッドのアレコレ (20)

Applying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedApplying 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)Data Structure in C (Lab Programs)
Data Structure in C (Lab Programs)
 
Objective-c Runtime
Objective-c RuntimeObjective-c Runtime
Objective-c Runtime
 
droidQuery: The Android port of jQuery
droidQuery: The Android port of jQuerydroidQuery: The Android port of jQuery
droidQuery: The Android port of jQuery
 
Part II: LLVM Intermediate Representation
Part II: LLVM Intermediate RepresentationPart II: LLVM Intermediate Representation
Part II: LLVM Intermediate Representation
 
Chapter 7 functions (c)
Chapter 7 functions (c)Chapter 7 functions (c)
Chapter 7 functions (c)
 
Coding Ajax
Coding AjaxCoding Ajax
Coding Ajax
 
Swift internals
Swift internalsSwift internals
Swift internals
 
Introduction to Spring MVC
Introduction to Spring MVCIntroduction to Spring MVC
Introduction to Spring MVC
 
Live Updating Swift Code
Live Updating Swift CodeLive Updating Swift Code
Live Updating Swift Code
 
Coding Ajax
Coding AjaxCoding Ajax
Coding Ajax
 
Treinamento Qt básico - aula II
Treinamento Qt básico - aula IITreinamento Qt básico - aula II
Treinamento Qt básico - aula II
 
Array
ArrayArray
Array
 
Advance java
Advance javaAdvance java
Advance java
 
Awt components
Awt componentsAwt components
Awt components
 
Models, controllers and views
Models, controllers and viewsModels, controllers and views
Models, controllers and views
 
Unit 3
Unit 3 Unit 3
Unit 3
 
var, let in SIL
var, let in SILvar, let in SIL
var, let in SIL
 
Practical Model View Programming (Roadshow Version)
Practical Model View Programming (Roadshow Version)Practical Model View Programming (Roadshow Version)
Practical Model View Programming (Roadshow Version)
 
Hidden Gems in Swift
Hidden Gems in SwiftHidden Gems in Swift
Hidden Gems in Swift
 

Kürzlich hochgeladen

(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordCCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordAsst.prof M.Gokilavani
 
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur EscortsRussian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...Christo Ananth
 
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...ranjana rawat
 
Introduction to Multiple Access Protocol.pptx
Introduction to Multiple Access Protocol.pptxIntroduction to Multiple Access Protocol.pptx
Introduction to Multiple Access Protocol.pptxupamatechverse
 
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSMANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSSIVASHANKAR N
 
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
Processing & Properties of Floor and Wall Tiles.pptx
Processing & Properties of Floor and Wall Tiles.pptxProcessing & Properties of Floor and Wall Tiles.pptx
Processing & Properties of Floor and Wall Tiles.pptxpranjaldaimarysona
 
Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)simmis5
 
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...ranjana rawat
 
Booking open Available Pune Call Girls Pargaon 6297143586 Call Hot Indian Gi...
Booking open Available Pune Call Girls Pargaon  6297143586 Call Hot Indian Gi...Booking open Available Pune Call Girls Pargaon  6297143586 Call Hot Indian Gi...
Booking open Available Pune Call Girls Pargaon 6297143586 Call Hot Indian Gi...Call Girls in Nagpur High Profile
 
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdfONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdfKamal Acharya
 
Introduction to IEEE STANDARDS and its different types.pptx
Introduction to IEEE STANDARDS and its different types.pptxIntroduction to IEEE STANDARDS and its different types.pptx
Introduction to IEEE STANDARDS and its different types.pptxupamatechverse
 
KubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlyKubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlysanyuktamishra911
 
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Bookingdharasingh5698
 
UNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its PerformanceUNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its Performancesivaprakash250
 

Kürzlich hochgeladen (20)

DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINEDJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
 
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordCCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
 
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur EscortsRussian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
 
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
 
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
 
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
 
Introduction to Multiple Access Protocol.pptx
Introduction to Multiple Access Protocol.pptxIntroduction to Multiple Access Protocol.pptx
Introduction to Multiple Access Protocol.pptx
 
Roadmap to Membership of RICS - Pathways and Routes
Roadmap to Membership of RICS - Pathways and RoutesRoadmap to Membership of RICS - Pathways and Routes
Roadmap to Membership of RICS - Pathways and Routes
 
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSMANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
 
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
 
Processing & Properties of Floor and Wall Tiles.pptx
Processing & Properties of Floor and Wall Tiles.pptxProcessing & Properties of Floor and Wall Tiles.pptx
Processing & Properties of Floor and Wall Tiles.pptx
 
Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)
 
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
 
Booking open Available Pune Call Girls Pargaon 6297143586 Call Hot Indian Gi...
Booking open Available Pune Call Girls Pargaon  6297143586 Call Hot Indian Gi...Booking open Available Pune Call Girls Pargaon  6297143586 Call Hot Indian Gi...
Booking open Available Pune Call Girls Pargaon 6297143586 Call Hot Indian Gi...
 
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdfONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
 
Introduction to IEEE STANDARDS and its different types.pptx
Introduction to IEEE STANDARDS and its different types.pptxIntroduction to IEEE STANDARDS and its different types.pptx
Introduction to IEEE STANDARDS and its different types.pptx
 
KubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlyKubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghly
 
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
 
UNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its PerformanceUNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its Performance
 

Swiftとメソッドのアレコレ

  • 6. objc_msgSend 6 Class IMP void aFunction(id self, SEL _cmd) { … } SEL 処理はCの関数と同等のIMPに存在 IMPへの参照とSelectorの組を持つ
  • 12. Swiftは何故速い? 12 @interface A : NSObject @property (nonatomic) NSString *str; @property (nonatomic) NSInteger integer; @end @implementation A - (void)function { } @end
  • 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() { } }
  • 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ではない
  • 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 関数を直接実行している
  • 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
  • 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型
  • 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 } 型引数 
  • 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)
  • 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を利用
  • 70. optional func 70 @objc protocol Delegate: NSObjectProtocol { optional func function() }
  • 71. 71 swiftc -emit-ir source.swift > source.ll struct/enum
  • 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を生成してラッピング