记录/objc2/object_setClass做了啥

inline Class 
objc_object::changeIsa(Class newCls)
{
    // This is almost always true but there are 
    // enough edge cases that we can't assert it.
    // assert(newCls->isFuture()  || 
    //        newCls->isInitializing()  ||  newCls->isInitialized());

    assert(!isTaggedPointer()); 

    isa_t oldisa;
    isa_t newisa;+构建新对象体 isa_t

    bool sideTableLocked = false;
    bool transcribeToSideTable = false;

    do {
        transcribeToSideTable = false;
        oldisa = LoadExclusive(&isa.bits);
        if ((oldisa.bits == 0  ||  oldisa.nonpointer)  &&
            !newCls->isFuture()  &&  newCls->canAllocNonpointer())
        {
            // 0 -> nonpointer
            // nonpointer -> nonpointer
#if SUPPORT_INDEXED_ISA
            if (oldisa.bits == 0) newisa.bits = ISA_INDEX_MAGIC_VALUE;
            else newisa = oldisa;
            // isa.magic is part of ISA_MAGIC_VALUE
            // isa.nonpointer is part of ISA_MAGIC_VALUE
            newisa.has_cxx_dtor = newCls->hasCxxDtor();
            assert(newCls->classArrayIndex() > 0);
            newisa.indexcls = (uintptr_t)newCls->classArrayIndex();
#else
        
        
if (oldisa.bits == 0) newisa.bits = ISA_MAGIC_VALUE; else newisa = oldisa; // isa.magic is part of ISA_MAGIC_VALUE // isa.nonpointer is part of ISA_MAGIC_VALUE newisa.has_cxx_dtor = newCls->hasCxxDtor(); newisa.shiftcls = (uintptr_t)newCls >> 3;+改变类型的指针,存储的时候清除低位没用的3位
#endif } else if (oldisa.nonpointer) { // nonpointer -> raw pointer // Need to copy retain count et al to side table. // Acquire side table lock before setting isa to // prevent races such as concurrent -release.
        +如果是TargetPoint对象,标记为需要转移其他数据
if (!sideTableLocked) sidetable_lock(); sideTableLocked = true; transcribeToSideTable = true; newisa.cls = newCls; } else { // raw pointer -> raw pointer newisa.cls = newCls; }
      +上面在为新对象体转移数据 }
while (!StoreExclusive(&isa.bits, oldisa.bits, newisa.bits));+将数据覆盖对象体,内部原子的比较并交换 if (transcribeToSideTable) { // Copy oldisa's retain count et al to side table. // oldisa.has_assoc: nothing to do // oldisa.has_cxx_dtor: nothing to do
      +被标记为转移其他数据,转移引用计数器-1标识,转移是否正在dealloc的标识,转移所引用标识
sidetable_moveExtraRC_nolock(oldisa.extra_rc, oldisa.deallocating, oldisa.weakly_referenced); } if (sideTableLocked) sidetable_unlock(); if (oldisa.nonpointer) { #if SUPPORT_INDEXED_ISA return classForIndex(oldisa.indexcls); #else return (Class)((uintptr_t)oldisa.shiftcls << 3); #endif } else { return oldisa.cls; } }

 

posted @ 2019-05-21 23:06  米太白  阅读(532)  评论(0编辑  收藏  举报