實(shí)例與類的對(duì)比 - swift_0x03

接上篇:編譯過程補(bǔ)充

語法分析 Parse --> 語義分析 Sema --> SILGen --> IRGen --> 匯編 --> MachO

網(wǎng)上找到一張圖片:

Swift 編譯過程

具體命令:

-dump—parse --> -dump—ast --> -emit-silgen --> -emit-sil --> -emit-ir

Swift 對(duì)象創(chuàng)建過程 —— allocating_init()

創(chuàng)建一個(gè)swift對(duì)象會(huì)調(diào)用類的__allocating_init()方法秆乳,然后調(diào)用私有方法_swift_allocObject_()方法

這個(gè)方法實(shí)現(xiàn)在 HeapObject.cpp 中:

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;
}

swift_slowAlloc()

首先使用 assert 檢查了傳遞的參數(shù)的內(nèi)存對(duì)齊規(guī)范养交,然后調(diào)用了 swift_slowAlloc(requiredSize, requiredAlignmentMask)围小,方法如下绍哎,在Heap.cpp中

void *swift::swift_slowAlloc(size_t size, size_t alignMask) {
  void *p;
  // This check also forces "default" alignment to use AlignedAlloc.
  if (alignMask <= MALLOC_ALIGN_MASK) {
#if defined(__APPLE__)
    p = malloc_zone_malloc(DEFAULT_ZONE(), size);
#else
    p = malloc(size);
#endif
  } else {
    size_t alignment = (alignMask == ~(size_t(0)))
                           ? _swift_MinAllocationAlignment
                           : alignMask + 1;
    p = AlignedAlloc(size, alignment);
  }
  if (!p) swift::crash("Could not allocate memory.");
  return p;
}

這里看到了熟悉的 malloc(size),OC也是調(diào)用的這個(gè)碉碉。

HeapObject

然后回到_swift_allocObject_()方法边苹,繼續(xù)調(diào)用了

  new (object) HeapObject(metadata);

使用入?yún)?metadata 調(diào)用 HeapObject 的初始化方法,創(chuàng)建了一個(gè) HeapObject杜顺。

HeapObject 是一個(gè)結(jié)構(gòu)體财搁,聲明在 HeapObject.h 文件中

/// The Swift heap-object header.
/// This must match RefCountedStructTy in IRGen.
struct HeapObject {
  /// This is always a valid pointer to a metadata object.
  HeapMetadata const *metadata;

  SWIFT_HEAPOBJECT_NON_OBJC_MEMBERS;

#ifndef __swift__
  HeapObject() = default;

// 初始化函數(shù)
  // Initialize a HeapObject header as appropriate for a newly-allocated object.
  constexpr HeapObject(HeapMetadata const *newMetadata) 
    : metadata(newMetadata)
    , refCounts(InlineRefCounts::Initialized)
  { }
  
  // Initialize a HeapObject header for an immortal object
  constexpr HeapObject(HeapMetadata const *newMetadata,
                       InlineRefCounts::Immortal_t immortal)
  : metadata(newMetadata)
  , refCounts(InlineRefCounts::Immortal)
  { }

#ifndef NDEBUG
  void dump() const LLVM_ATTRIBUTE_USED;
#endif

#endif // __swift__
};

可以看到成員變量:

  1. metadata指針
  2. SWIFT_HEAPOBJECT_NON_OBJC_MEMBERS

所以一個(gè) HeapObject 對(duì)象什么屬性都不聲明,就默認(rèn)占用16字節(jié)的大小躬络。

Swift 對(duì)象是一個(gè) HeapObject尖奔,默認(rèn)占用16字節(jié)。
OC 對(duì)象是一個(gè)結(jié)構(gòu)體 objc_object,默認(rèn)只有 isa 指針提茁,占用8字節(jié)淹禾。

isa指針具體解釋如下圖,更多詳情參考 footnote 第一個(gè)鏈接茴扁。


-w600

類結(jié)構(gòu)

上面創(chuàng)建實(shí)例對(duì)象的方法有一個(gè)入?yún)⒘宀恚凶鰉etadata,也叫元數(shù)據(jù)峭火,這個(gè)就好像OC的class一樣毁习,類是創(chuàng)建實(shí)例對(duì)象的模板,就是這個(gè)metadata卖丸。

HeapMetadata const *metadata;

點(diǎn)擊可以查看到 HeapMetadata 的定義:

using HeapMetadata = TargetHeapMetadata<InProcess>;

TargetHeapMetadata<InProcess> 類型的別名纺且,繼續(xù)看到 TargetHeapMetadata 結(jié)構(gòu)體的定義:

struct TargetHeapMetadata : TargetMetadata<Runtime> {
  using HeaderType = TargetHeapMetadataHeader<Runtime>;

  TargetHeapMetadata() = default;
  constexpr TargetHeapMetadata(MetadataKind kind)
    : TargetMetadata<Runtime>(kind) {}
#if SWIFT_OBJC_INTEROP
  constexpr TargetHeapMetadata(TargetAnyClassMetadata<Runtime> *isa)
    : TargetMetadata<Runtime>(isa) {}
#endif
};

TargetHeapMetadata 繼承自 TargetMetadata。

class的類型其實(shí)是TargetMetadata的 kind 傳入 class 的 kind坯苹,具體的類是TargetAnyCkassMetadata隆檀,這里不是特別確定,但是看到這個(gè)類確實(shí)是如此的粹湃。

類相關(guān)的繼承關(guān)系是這樣的:

TargetClassMetadata → TargetAnyClassMetadata → TargetHeapMetadata → TargetMetadata<Runtime>

UML

image

如果 swift 的類繼承了 OC 的類恐仑,那么這個(gè) kind 就會(huì)指向 objc_class。

如上圖为鳄,OC class 結(jié)構(gòu)為:objc_class → objc_object裳仆。

objc_class 結(jié)構(gòu)如下:

struct objc_class : objc_object {
    // Class ISA;
    Class superclass;
    cache_t cache;             // formerly cache pointer and vtable
    class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags
    class_rw_t *data() const {
        return bits.data();
    }
}

這里先后存儲(chǔ)的東西分四個(gè):

  1. 繼承來的 isa 結(jié)構(gòu)的指針,占8字節(jié)
  2. superClass 的 Class 指針孤钦,占8字節(jié)
  3. cache類型歧斟,本篇跳過。
  4. class_data_bits_t類型的bits偏形。

關(guān)于 class_data_bits_t静袖、class_rw_tclass_ro_t俊扭、class_rwe_t队橙,請(qǐng)參考Footnote第一個(gè)鏈接。

Footnote

OC Runtime 底層類結(jié)構(gòu)2020最新

官方SIL語法文檔

官方SIL編程手冊

簡書Swift進(jìn)階

Swift之源碼編譯的環(huán)境搭建和編譯流程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末萨惑,一起剝皮案震驚了整個(gè)濱河市捐康,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌庸蔼,老刑警劉巖解总,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異姐仅,居然都是意外死亡花枫,警方通過查閱死者的電腦和手機(jī)刻盐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乌昔,“玉大人隙疚,你說我怎么就攤上這事】牡溃” “怎么了供屉?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長溺蕉。 經(jīng)常有香客問我伶丐,道長,這世上最難降的妖魔是什么疯特? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任哗魂,我火速辦了婚禮,結(jié)果婚禮上漓雅,老公的妹妹穿的比我還像新娘录别。我一直安慰自己,他們只是感情好邻吞,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布组题。 她就那樣靜靜地躺著,像睡著了一般抱冷。 火紅的嫁衣襯著肌膚如雪崔列。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天旺遮,我揣著相機(jī)與錄音赵讯,去河邊找鬼。 笑死耿眉,一個(gè)胖子當(dāng)著我的面吹牛边翼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鸣剪,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼组底,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了西傀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤桶癣,失蹤者是張志新(化名)和其女友劉穎拥褂,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體牙寞,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡饺鹃,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年莫秆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悔详。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡镊屎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出茄螃,到底是詐尸還是另有隱情缝驳,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布归苍,位于F島的核電站用狱,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏拼弃。R本人自食惡果不足惜夏伊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望吻氧。 院中可真熱鬧溺忧,春花似錦、人聲如沸盯孙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽镀梭。三九已至刀森,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間报账,已是汗流浹背研底。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留透罢,地道東北人衷模。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像才漆,于是被迫代替她去往敵國和親封豪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

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