Improve copying and moving weak refs.

Fixes a bug introduced (replacing a similar bug) in the last rewrite of
objc_moveWeak.  This version should now be correct.

objc_copyWeak was implemented in a naive way, which had a lot more
overhead than required.
main
David Chisnall 8 years ago
parent 458bd3c7a2
commit e5b4468867

29
arc.m

@ -802,7 +802,24 @@ id objc_loadWeak(id* object)
void objc_copyWeak(id *dest, id *src)
{
objc_release(objc_initWeak(dest, objc_loadWeakRetained(src)));
// Don't retain or release. While the weak ref lock is held, we know that
// the object can't be deallocated, so we just move the value and update
// the weak reference table entry to indicate the new address.
LOCK_FOR_SCOPE(&weakRefLock);
id obj;
WeakRef *srcRef;
WeakRef *dstRef;
loadWeakPointer(dest, &obj, &dstRef);
loadWeakPointer(src, &obj, &srcRef);
*dest = *src;
if (srcRef)
{
srcRef->weak_count++;
}
if (dstRef)
{
weakRefRelease(dstRef);
}
}
void objc_moveWeak(id *dest, id *src)
@ -811,10 +828,16 @@ void objc_moveWeak(id *dest, id *src)
// the object can't be deallocated, so we just move the value and update
// the weak reference table entry to indicate the new address.
LOCK_FOR_SCOPE(&weakRefLock);
WeakRef *oldRef = weak_ref_table_get(weakRefs, *dest);
id obj;
WeakRef *oldRef;
// If the destination is a weak ref, free it.
loadWeakPointer(dest, &obj, &oldRef);
*dest = *src;
*src = nil;
weakRefRelease(oldRef);
if (oldRef != NULL)
{
weakRefRelease(oldRef);
}
}
void objc_destroyWeak(id* obj)

Loading…
Cancel
Save