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