接上篇:編譯過程補(bǔ)充
語法分析 Parse --> 語義分析 Sema --> SILGen --> IRGen --> 匯編 --> MachO
網(wǎng)上找到一張圖片:
具體命令:
-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__
};
可以看到成員變量:
-
metadata
指針 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è)鏈接茴扁。
類結(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
如果 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è):
- 繼承來的
isa
結(jié)構(gòu)的指針,占8字節(jié) - superClass 的 Class 指針孤钦,占8字節(jié)
- cache類型歧斟,本篇跳過。
- class_data_bits_t類型的bits偏形。
關(guān)于 class_data_bits_t
静袖、class_rw_t
、class_ro_t
俊扭、class_rwe_t
队橙,請(qǐng)參考Footnote第一個(gè)鏈接。