isa结构分析

首先来看下c++

objc isa主要源码

#include "isa.h"

union isa_t {
    isa_t() { }
    isa_t(uintptr_t value) : bits(value) { }

    Class cls;
    uintptr_t bits;
#if defined(ISA_BITFIELD)
    struct {
        ISA_BITFIELD;  // defined in isa.h
    };
#endif
};
复制代码

经过源码咱们发现isa是一个联合体union, cls 与bits是互斥关系。markdown

在看下ISA_BITFIELD宏定义 架构

# if __arm64__ //手机端
#   define ISA_MASK        0x0000000ffffffff8ULL
#   define ISA_MAGIC_MASK  0x000003f000000001ULL
#   define ISA_MAGIC_VALUE 0x000001a000000001ULL
#   define ISA_BITFIELD                                                      \
      uintptr_t nonpointer        : 1;                                       \
      uintptr_t has_assoc         : 1;                                       \
      uintptr_t has_cxx_dtor      : 1;                                       \
      uintptr_t shiftcls          : 33; /*MACH_VM_MAX_ADDRESS 0x1000000000*/ \
      uintptr_t magic             : 6;                                       \
      uintptr_t weakly_referenced : 1;                                       \
      uintptr_t deallocating      : 1;                                       \
      uintptr_t has_sidetable_rc  : 1;                                       \
      uintptr_t extra_rc          : 19
#   define RC_ONE   (1ULL<<45)
#   define RC_HALF  (1ULL<<18)

# elif __x86_64__ //终点架构(模拟器/mac)
#   define ISA_MASK        0x00007ffffffffff8ULL
#   define ISA_MAGIC_MASK  0x001f800000000001ULL
#   define ISA_MAGIC_VALUE 0x001d800000000001ULL
#   define ISA_BITFIELD                                                        \
      uintptr_t nonpointer        : 1;                                         \
      uintptr_t has_assoc         : 1;                                         \
      uintptr_t has_cxx_dtor      : 1;                                         \
      uintptr_t shiftcls          : 44; /*MACH_VM_MAX_ADDRESS 0x7fffffe00000*/ \
      uintptr_t magic             : 6;                                         \
      uintptr_t weakly_referenced : 1;                                         \
      uintptr_t deallocating      : 1;                                         \
      uintptr_t has_sidetable_rc  : 1;                                         \
      uintptr_t extra_rc          : 8
#   define RC_ONE   (1ULL<<56)
#   define RC_HALF  (1ULL<<7)

# else
#   error unknown architecture for packed isa
# endif

// SUPPORT_PACKED_ISA
#endif
复制代码

咱们来将其简单分享分析一下ide

  • 位1(nonpointer) : 表示是否对isa指针开启指针优化,0表示纯isa指针,1表示不⽌是类对象地址,isa中包含了类信息、对象的引⽤计数等。函数

  • 位2( has_assoc) : 关联对象标志位,1——存在,0——没有源码分析

  • 位3(has_cxx_dtor): 该对象是否有C++或者Objc的析构器,若是有析构函数,则须要作析构逻辑,若是没有,则能够更快的释放对象。优化

  • 位4(shiftcls) : 存储类指针的值。开启指针优化的状况下,在arm64架构中有33位⽤来存储类指针。ui

  • 位5(magic) : ⽤于调试器判断当前对象是真的对象仍是没有初始化的空间this

  • 位6(weakly_referenced) : 对象是否被指向或者曾经指向⼀个ARC的弱变量,没有弱引⽤的对象能够更快释放。spa

  • 位7(deallocating) : 标志对象是否正在释放内存

  • 位8(has_sidetable_rc) : 当对象引⽤计数⼤于10时,则须要借⽤该变量存储进位

  • 位9(extra_rc): 当表示该对象的引⽤计数值,其实是引⽤计数值减1, 例如,若是对象的引⽤计数为10,那么extra_rc为9。若是引⽤计数⼤于10,则须要使⽤到下⾯的has_sidetable_rc

接下来咱们来看下对象释放时候的一些处理

dealloc源码分析

inline void
objc_object::rootDealloc()
{
    if (isTaggedPointer()) return;  // fixme necessary?

    if (fastpath(isa.nonpointer  &&  
                 !isa.weakly_referenced  &&  
                 !isa.has_assoc  &&  //关联对象
                 !isa.has_cxx_dtor  &&  
                 !isa.has_sidetable_rc))//闪链表
    {
        assert(!sidetable_present());
        free(this);//移除处理
    } 
    else {
        object_dispose((id)this);//释放
    }
}

id 
object_dispose(id obj)
{
    if (!obj) return nil;

    objc_destructInstance(obj);    
    free(obj);

    return nil;
}

objc_destructInstance(obj):
void *objc_destructInstance(id obj) 
{
    if (obj) {
        // Read all of the flags at once for performance.
        bool cxx = obj->hasCxxDtor();
        bool assoc = obj->hasAssociatedObjects();//关联对象

        // This order is important.
        if (cxx) object_cxxDestruct(obj);//c++ 析构
        if (assoc) _object_remove_assocations(obj);//移除关联对象
        obj->clearDeallocating();
    }

    return obj;
}

obj->clearDeallocating():
inline void 
objc_object::clearDeallocating()
{
    if (slowpath(!isa.nonpointer)) {
        // Slow path for raw pointer isa.
        sidetable_clearDeallocating();
    }
    else if (slowpath(isa.weakly_referenced  ||  isa.has_sidetable_rc)) {
        // Slow path for non-pointer isa with weak refs and/or side table data.
        clearDeallocating_slow();
    }

    assert(!sidetable_present());
}
复制代码
相关文章
相关标签/搜索