InlineRefCounts refcounts
typedef RefCounts<InlineRefCountBits> InlineRefCounts;
typedef RefCounts<SideTableRefCountBits> SideTableRefCounts;
RefCounts是一个模版类,主要看尖括号里的东西。
class RefCounts { std::atomic<RefCountBits> refCounts; .... }
然后看RefCountBits是啥
typedef RefCountBitsT<RefCountIsInline> InlineRefCountBits;
又是一个别名,和上面操作一样,RefCountBitsT
是一个模版类,但RefCountIsInline
只是一个枚举,所以我们深入看下RefCountBitsT
这个RefCountBitsT里面有一个属性
BitsType bits;
BitsType分为32位和64位,现在电脑基本都是64位,这个bits才是引用计数的核心东西。是一个无符号64位整型
所以InlineRefCounts
目前就是一个uint64_t
,被RefCountBitsT
操作着
名字 | 范围(起始位置,长度 ) | 作用 |
---|---|---|
PureSwiftDeallocMask | (0, 1) | 对象是否需要调用ObjC运行时来解除分配 |
UnownedRefCountMask | (1, 31) | 无主引用计数 |
IsImmortalMask | (0, 32) | 所有bit设置后,对象不会释放或具有refcount |
IsDeinitingMask | (32, 1) | 是否在进行反初始化 |
StrongExtraRefCountMask | (33, 30) | 强引用计数 |
UseSlowRCMask | (63, 1) | 使用慢RC |
SideTableMask | (0, 62) | 存放SideTable地址 |
SideTableUnusedLowBits | SideTable没有用到的低字节位数 | |
SideTableMarkMask | (62, 1) | 是否存放是SideTable |
弱引用
swift_weakinit.
调用 nativeInit方法 ,
调用formweakreference
然后是allocatesidetable方法
template <>
HeapObjectSideTableEntry* RefCounts<InlineRefCountBits>::allocateSideTable(bool failIfDeiniting)
{
//获取当前的引用计数存给oldbits
auto oldbits = refCounts.load(SWIFT_MEMORY_ORDER_CONSUME);
// oldbits中存放的可能已经是生成好的SideTable地址,所以判断一下,如果能取到SideTable,那么直接返回出去,因为已经创建过了
if (oldbits.hasSideTable()) {
// Already have a side table. Return it.
return oldbits.getSideTable();
}
//如果正在销毁中,那么直接返回空指针
else if (failIfDeiniting && oldbits.getIsDeiniting()) {
// Already past the start of deinit. Do nothing.
return nullptr;
}
// Preflight passed. Allocate a side table.
// 生成了SideTable存给变量side
HeapObjectSideTableEntry *side = new HeapObjectSideTableEntry(getHeapObject());
// 这个比较关键,这个方法把变量side的地址做了一定的操作,形成新的newbits,这个方法下面会详细讲
auto newbits = InlineRefCountBits(side);
do {
//这里又判断oldbits里存的是否是SideTable,是的话,返回老的SideTable,删除刚才我们创建的SideTable,这个好像和开头重叠了,猜测可能是多线程的原因吧。
if (oldbits.hasSideTable()) {
// Already have a side table. Return it and delete ours.
// Read before delete to streamline barriers.
auto result = oldbits.getSideTable();
delete side;
return result;
}
else if (failIfDeiniting && oldbits.getIsDeiniting()) {
// Already past the start of deinit. Do nothing.
return nullptr;
}
// 把当前的引用计数存入SideTable中
side->initRefCounts(oldbits);
//CAS
} while (! refCounts.compare_exchange_weak(oldbits, newbits,
std::memory_order_release,
std::memory_order_relaxed));
return side;
}
这个类就是sidetable的结构
class HeapObjectSideTableEntry {
// FIXME: does object need to be atomic?
std::atomic<HeapObject*> object;
SideTableRefCounts refCounts;
...
}
第一个是指向的对象,第二个是sidetable的引用计数,是SideTableRefCounts,没有弱引用的时候是InlineRefCounts。
参考文章和图片:Swift引用计数的底层分析 - 掘金