Skip to content

Commit

Permalink
Better recovery when things are done in the wrong order.
Browse files Browse the repository at this point in the history
  • Loading branch information
theraven committed Jul 11, 2011
1 parent 3754c9f commit e69ed06
Showing 1 changed file with 31 additions and 23 deletions.
54 changes: 31 additions & 23 deletions arc.m
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,30 @@ static inline void release(id obj)
[obj release];
}

static inline void initAutorelease(void)
{
if (Nil == AutoreleasePool)
{
AutoreleasePool = objc_getRequiredClass("NSAutoreleasePool");
if (Nil == AutoreleasePool)
{
useARCAutoreleasePool = YES;
}
else
{
[AutoreleasePool class];
useARCAutoreleasePool = class_respondsToSelector(AutoreleasePool,
SELECTOR(_ARCCompatibleAutoreleasePool));
NewAutoreleasePool = class_getMethodImplementation(object_getClass(AutoreleasePool),
SELECTOR(new));
DeleteAutoreleasePool = class_getMethodImplementation(AutoreleasePool,
SELECTOR(release));
AutoreleaseAdd = class_getMethodImplementation(object_getClass(AutoreleasePool),
SELECTOR(addObject:));
}
}
}

static inline id autorelease(id obj)
{
//fprintf(stderr, "Autoreleasing %p\n", obj);
Expand All @@ -200,7 +224,11 @@ static inline id autorelease(id obj)
}
if (objc_test_class_flag(obj->isa, objc_class_flag_fast_arc))
{
AutoreleaseAdd(AutoreleasePool, SELECTOR(addObject:), obj);
initAutorelease();
if (0 != AutoreleaseAdd)
{
AutoreleaseAdd(AutoreleasePool, SELECTOR(addObject:), obj);
}
return obj;
}
return [obj autorelease];
Expand All @@ -209,26 +237,6 @@ static inline id autorelease(id obj)

void *objc_autoreleasePoolPush(void)
{
if (Nil == AutoreleasePool)
{
AutoreleasePool = objc_getRequiredClass("NSAutoreleasePool");
if (Nil == AutoreleasePool)
{
useARCAutoreleasePool = YES;
}
else
{
[AutoreleasePool class];
useARCAutoreleasePool = class_respondsToSelector(AutoreleasePool,
SELECTOR(_ARCCompatibleAutoreleasePool));
NewAutoreleasePool = class_getMethodImplementation(object_getClass(AutoreleasePool),
SELECTOR(new));
DeleteAutoreleasePool = class_getMethodImplementation(AutoreleasePool,
SELECTOR(release));
AutoreleaseAdd = class_getMethodImplementation(object_getClass(AutoreleasePool),
SELECTOR(addObject:));
}
}
if (useARCAutoreleasePool)
{
struct arc_tls* tls = getARCThreadData();
Expand All @@ -239,6 +247,8 @@ static inline id autorelease(id obj)
return (NULL != tls->pool) ? tls->pool->insert : NULL;
}
}
initAutorelease();
if (0 == NewAutoreleasePool) { return NULL; }
return NewAutoreleasePool(AutoreleasePool, SELECTOR(new));
}
void objc_autoreleasePoolPop(void *pool)
Expand All @@ -253,8 +263,6 @@ void objc_autoreleasePoolPop(void *pool)
return;
}
}
// TODO: Keep a small pool of autorelease pools per thread and allocate
// from there.
DeleteAutoreleasePool(pool, SELECTOR(release));
struct arc_tls* tls = getARCThreadData();
if (tls && tls->returnRetained)
Expand Down

0 comments on commit e69ed06

Please sign in to comment.