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;
}
}