Add interfaces for better integration with Foundation.

main
David Chisnall 8 years ago
parent bdc20a8bab
commit 458bd3c7a2

68
arc.m

@ -175,17 +175,8 @@ static const long weak_mask = ((size_t)1)<<((sizeof(size_t)*8)-1);
*/
static const long refcount_mask = ~weak_mask;
static inline id retain(id obj)
id objc_retain_fast_np(id obj)
{
if (isSmallObject(obj)) { return obj; }
Class cls = obj->isa;
if ((Class)&_NSConcreteMallocBlock == cls ||
(Class)&_NSConcreteStackBlock == cls)
{
return Block_copy(obj);
}
if (objc_test_class_flag(cls, objc_class_flag_fast_arc))
{
uintptr_t *refCount = ((uintptr_t*)obj) - 1;
uintptr_t refCountVal = __sync_fetch_and_add(refCount, 0);
uintptr_t newVal = refCountVal;
@ -221,26 +212,26 @@ static inline id retain(id obj)
newVal = __sync_val_compare_and_swap(refCount, refCountVal, updated);
} while (newVal != refCountVal);
return obj;
}
return [obj retain];
}
static inline void release(id obj)
static inline id retain(id obj)
{
if (isSmallObject(obj)) { return; }
if (isSmallObject(obj)) { return obj; }
Class cls = obj->isa;
if (cls == &_NSConcreteMallocBlock)
{
_Block_release(obj);
return;
}
if ((cls == &_NSConcreteStackBlock) ||
(cls == &_NSConcreteGlobalBlock))
if ((Class)&_NSConcreteMallocBlock == cls ||
(Class)&_NSConcreteStackBlock == cls)
{
return;
return Block_copy(obj);
}
if (objc_test_class_flag(cls, objc_class_flag_fast_arc))
{
return objc_retain_fast_np(obj);
}
return [obj retain];
}
BOOL objc_release_fast_no_destroy_np(id obj)
{
uintptr_t *refCount = ((uintptr_t*)obj) - 1;
uintptr_t refCountVal = __sync_fetch_and_add(refCount, 0);
uintptr_t newVal = refCountVal;
@ -252,7 +243,7 @@ static inline void release(id obj)
// If the reference count is saturated, don't decrement it.
if (realCount == refcount_mask)
{
return;
return NO;
}
realCount--;
isWeak = (refCountVal & weak_mask) == weak_mask;
@ -269,11 +260,39 @@ static inline void release(id obj)
{
if (!objc_delete_weak_refs(obj))
{
return;
return NO;
}
}
return YES;
}
return NO;
}
void objc_release_fast_np(id obj)
{
if (objc_release_fast_no_destroy_np(obj))
{
[obj dealloc];
}
}
static inline void release(id obj)
{
if (isSmallObject(obj)) { return; }
Class cls = obj->isa;
if (cls == &_NSConcreteMallocBlock)
{
_Block_release(obj);
return;
}
if ((cls == &_NSConcreteStackBlock) ||
(cls == &_NSConcreteGlobalBlock))
{
return;
}
if (objc_test_class_flag(cls, objc_class_flag_fast_arc))
{
objc_release_fast_np(obj);
return;
}
[obj release];
@ -375,7 +394,6 @@ unsigned long objc_arc_autorelease_count_for_object_np(id obj)
return count;
}
void *objc_autoreleasePoolPush(void)
{
initAutorelease();

@ -32,6 +32,12 @@ id objc_loadWeakRetained(id* obj);
* Retains the argument. Equivalent to [obj retain].
*/
id objc_retain(id obj);
/**
* Retains the argument, assuming that the argument is a normal object and has
* its reference count managed by the runtime.
* This is intended to implement `-retain` in ARC-compatible root classes.
*/
id objc_retain_fast_np(id obj) OBJC_NONPORTABLE;
/**
* Retains and autoreleases an object. Equivalent to [[obj retain] autorelease].
*/
@ -85,6 +91,26 @@ void objc_destroyWeak(id* addr);
* Equivalent to objc_copyWeak(), but may also set src to nil.
*/
void objc_moveWeak(id *dest, id *src);
/**
* Releases the argument, assuming that the argument is a normal object and has
* its reference count managed by the runtime. If the retain count reaches
* zero then all weak references will be zeroed and the object will be
* destroyed.
*
* This is intended to implement `-release` in ARC-compatible root
* classes.
*/
void objc_release_fast_np(id obj) OBJC_NONPORTABLE;
/**
* Releases the argument, assuming that the argument is a normal object and has
* its reference count managed by the runtime. If the retain count reaches
* zero then all weak references will be zeroed but the object will *NOT* be
* destroyed.
*
* This is intended to implement `NSDecrementExtraRefCountWasZero` for use with
* ARC-compatible classes.
*/
BOOL objc_release_fast_no_destroy_np(id obj) OBJC_NONPORTABLE;
/**
* Releases an object. Equivalent to [obj release].
*/

Loading…
Cancel
Save