記錄/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; } }
相關文章
相關標籤/搜索