002-Swift進(jìn)階-編譯簡介靴跛、sil文件的分析

一缀雳、swift編譯簡介

IOS開發(fā)的語言不管是OC還是swift,后端都是通過LLVM進(jìn)行編譯的梢睛,如下:


image.png

可以看到OC是clang編譯器肥印,編譯IR,然后在生成可執(zhí)行文件.0(機器碼),Swift是通過swift編譯器绝葡,編譯成IR深碱,然后生成可執(zhí)行文件。


image.png

二藏畅、SIL

swift使用的編譯器為swiftc敷硅,OC使用的為Clang。
swiftc命令查詢:swiftc -h
參考視頻:鏈接
參考文檔:SIL參考文檔

編譯成SIL文件:

swiftc -emit-sil main.swift >> main.sil && open main.sil 
//帶轉(zhuǎn)譯
swiftc -emit-sil main.swift | xcrun swift-demangle >> main.sil && open main.sil 

//IR
swiftc -emit-ir main.swift | xcrun swift-demangle >> main.ll && open main.ll

//UIKit
 swiftc -emit-sil -target x86_64-apple-ios13.5-simulator -sdk $(xcrun --show-sdk-path --sdk iphonesimulator) ViewController.swift > ViewController.sil

swift文件的入口函數(shù)


image.png
  • @main 是main.swift的入口函數(shù)愉阎,SIL中標(biāo)識符名稱以@作為前綴绞蹦,入口函數(shù)有兩個參數(shù),一個32位Int榜旦,一個指針幽七,一個返回值。
  • %0溅呢、%1......在SIL中叫做寄存器锉走,可以視為長量,賦值后不可更改藕届,在SIL中以累加數(shù)字的模式繼續(xù)使用挪蹭。這里所說的寄存器是虛擬的,最終運行到我們的機器上會使用真的寄存器休偶。
  • alloc_global 創(chuàng)建一個全局變量
  • global_addr 拿到全局變量的地址梁厉,賦值給%3
  • metatype 拿到LJTest的Metadata賦值給%4
  • 將__allocating_init 的函數(shù)地址賦值給%5
  • apply 調(diào)用 __allocating_init,并賦值給%6
  • 將%6的值存儲到%3
  • 構(gòu)建Int踏兜, 并return返回
  • Buildin LLVM指令格式

轉(zhuǎn)譯命令xcrun swift-demangle s4main2t1AA6LJTestCvp
寄存器讀却使恕:register read register read x8

xcode添加符號斷點


image.png

三、HeapObject.cpp中alloc_Object方法

image.png

1碱妆、初始化調(diào)度

  • 一個swift對象的內(nèi)存結(jié)構(gòu)HeapObject肉盹,默認(rèn)占用16字節(jié)大小,metadata疹尾,refCount
  • swift內(nèi)存分配過程調(diào)用順序:__allocating_init ---> swift_allocObject ---> swift_allocObject ---> swift_slowAlloc ---> Malloc

2上忍、打印占用空間大小

import Foundation
class LJTest{
    var age = 18
    var name: String = "swift"
}
var t1 = LJTest()
print(MemoryLayout<String>.stride)          //步長
print(MemoryLayout<String>.size)            //大小
print(class_getInstanceSize(LJTest.self))   //大小

3骤肛、類結(jié)構(gòu)探索

  • swift初始化函數(shù)swift_allocObject
    函數(shù)3個參數(shù):
    HeapMetadata const *metadata :元數(shù)據(jù)
    size_t requiredSize :大小
    size_t requiredAlignmentMask :對齊格式,
static HeapObject *_swift_allocObject_(HeapMetadata const *metadata,
                                       size_t requiredSize,
                                       size_t requiredAlignmentMask) {
  assert(isAlignmentMask(requiredAlignmentMask));
  auto object = reinterpret_cast<HeapObject *>(
      swift_slowAlloc(requiredSize, requiredAlignmentMask));

  // NOTE: this relies on the C++17 guaranteed semantics of no null-pointer
  // check on the placement new allocator which we have observed on Windows,
  // Linux, and macOS.
  new (object) HeapObject(metadata);

  // If leak tracking is enabled, start tracking this object.
  SWIFT_LEAKS_START_TRACKING_OBJECT(object);

  SWIFT_RT_TRACK_INVOCATION(object, swift_allocObject);

  return object;
}
  • Matedata
    TargetMetadata結(jié)構(gòu)體重包含一個屬性kind窍蓝,是一個存儲指針(isa)腋颠,是用來區(qū)分哪種類型的元數(shù)據(jù),在#include "MetadataKind.def"文件中存儲了所有的元數(shù)據(jù)類型吓笙。
    image.png

獲取當(dāng)前kind

/// Get the metadata kind.
  MetadataKind getKind() const {
    return getEnumeratedMetadataKind(Kind);
  }

獲取類對象
const TargetClassMetadata<Runtime> *getClassObject() const;
getClassObject()方法獲取的就是kind類型淑玫,通過getKind()方法獲取類型(MetadataKind::Class),

template<> inline const ClassMetadata *
  Metadata::getClassObject() const {
    switch (getKind()) {
    case MetadataKind::Class: {
      // Native Swift class metadata is also the class object.
      return static_cast<const ClassMetadata *>(this);
    }
    case MetadataKind::ObjCClassWrapper: {
      // Objective-C class objects are referenced by their Swift metadata wrapper.
      auto wrapper = static_cast<const ObjCClassWrapperMetadata *>(this);
      return wrapper->Class;
    }
    // Other kinds of types don't have class objects.
    default:
      return nullptr;
    }
  }
  • Matedata::Class
    TargetClassMetadata(ClassMetadata一樣面睛,所有的屬性) --> TargetAnyClassMetadata(kind, superclass, cacheData) --> TargetHeapMetadata(HeapMetadata) --> TargetMetadata(kind)

Metadata結(jié)構(gòu)體:

 struct swift_class_t: NSObject{
    void *kind; //isa, kind(unsigned long) 
    void *superClass;
    void *cacheData 
    void *data 
    uint32_t flags; //4 
    uint32_t instanceAddressOffset; //4 
    uint32_t instanceSize;//4 
    uint16_t instanceAlignMask; //2 
    uint16_t reserved; //2 
    uint32_t classSize; //4  
    uint32_t classAddressOffset; //4 
    void *description;  // ... 
};
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末絮蒿,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子叁鉴,更是在濱河造成了極大的恐慌歌径,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件亲茅,死亡現(xiàn)場離奇詭異,居然都是意外死亡狗准,警方通過查閱死者的電腦和手機克锣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來腔长,“玉大人袭祟,你說我怎么就攤上這事±谈剑” “怎么了巾乳?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鸟召。 經(jīng)常有香客問我胆绊,道長,這世上最難降的妖魔是什么欧募? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任压状,我火速辦了婚禮,結(jié)果婚禮上跟继,老公的妹妹穿的比我還像新娘种冬。我一直安慰自己,他們只是感情好舔糖,可當(dāng)我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布娱两。 她就那樣靜靜地躺著,像睡著了一般金吗。 火紅的嫁衣襯著肌膚如雪十兢。 梳的紋絲不亂的頭發(fā)上趣竣,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天,我揣著相機與錄音纪挎,去河邊找鬼期贫。 笑死,一個胖子當(dāng)著我的面吹牛异袄,可吹牛的內(nèi)容都是我干的通砍。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼烤蜕,長吁一口氣:“原來是場噩夢啊……” “哼封孙!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起讽营,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤虎忌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后橱鹏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體膜蠢,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年莉兰,在試婚紗的時候發(fā)現(xiàn)自己被綠了挑围。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡糖荒,死狀恐怖杉辙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情捶朵,我是刑警寧澤蜘矢,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站综看,受9級特大地震影響品腹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜红碑,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一珍昨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧句喷,春花似錦镣典、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至锡溯,卻和暖如春赶舆,著一層夾襖步出監(jiān)牢的瞬間哑姚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工芜茵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留叙量,地道東北人。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓九串,卻偏偏與公主長得像绞佩,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子猪钮,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容