예제 #1
0
__private_extern__ const void *__CFTypeCollectionRetain(CFAllocatorRef allocator, const void *ptr) {
    CFTypeRef cf = (CFTypeRef)ptr;
    // only collections allocated in the GC zone can opt-out of reference counting.
    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
        if (CFTYPE_IS_OBJC(cf)) return cf;  // do nothing for OBJC objects.
        if (auto_zone_is_valid_pointer(__CFCollectableZone, ptr)) {
            CFRuntimeClass *cfClass = __CFRuntimeClassTable[__CFGenericTypeID_inline(cf)];
            if (cfClass->version & _kCFRuntimeResourcefulObject) {
                // GC: If this a CF object in the GC heap that is marked resourceful, then
                // it must be retained keep it alive in a CF collection.
                // We're basically inlining CFRetain() here, to avoid an extra heap membership test.
                auto_zone_retain(__CFCollectableZone, (void*)cf);
            }
            else
                ;   // don't retain normal CF objects
            return cf;
        } else {
            // support constant CFTypeRef objects.
#if __LP64__
            uint32_t lowBits = ((CFRuntimeBase *)cf)->_rc;
#else
            uint32_t lowBits = ((CFRuntimeBase *)cf)->_cfinfo[CF_RC_BITS];
#endif
            if (lowBits == 0) return cf;
            // complain about non-GC objects in GC containers.
            CFLog(kCFLogLevelWarning, CFSTR("storing a non-GC object %p in a GC collection, break on CFCollection_non_gc_storage_error to debug."), cf);
            CFCollection_non_gc_storage_error();
            // XXX should halt, except Patrick is using this somewhere.
            // HALT;
        }
    }
    return CFRetain(cf);
}
예제 #2
0
파일: gc.c 프로젝트: 1nueve/MacRuby
void
ruby_xfree(void *ptr)
{
    if (ptr != NULL) {
	auto_zone_retain(__auto_zone, ptr);
	malloc_zone_free(__auto_zone, ptr);
    }
}
예제 #3
0
CFTypeRef CFRetain(CFTypeRef cf) {
    if (CF_IS_COLLECTABLE(cf)) {
        // always honor CFRetain's with a GC-visible retain.
        auto_zone_retain(__CFCollectableZone, (void*)cf);
        return cf;
    }
    CFTYPE_OBJC_FUNCDISPATCH0(CFTypeRef, cf, "retain");
    if (cf) __CFGenericAssertIsCF(cf);
    return _CFRetain(cf);
}
예제 #4
0
uint32_t
CFClass::cleanupObject(intptr_t op, CFTypeRef cf, bool &zap)
{
    // the default is to not throw away the object
    zap = false;
    
    bool isGC = CF_IS_COLLECTABLE(cf);
    
    uint32_t currentCount;
    SecCFObject *obj = SecCFObject::optional(cf);

    uint32_t oldCount;
    currentCount = obj->updateRetainCount(op, &oldCount);
    
    if (isGC)
    {
        auto_zone_t* zone = objc_collectableZone();
        
        if (op == -1 && oldCount == 0)
        {
            auto_zone_release(zone, (void*) cf);
        }
        else if (op == 1 && oldCount == 0 && currentCount == 1)
        {
           auto_zone_retain(zone, (void*) cf);
        }
        else if (op == -1 && oldCount == 1 && currentCount == 0)
        {
            /*
                To prevent accidental resurrection, just pull it out of the
                cache.
            */
            obj->aboutToDestruct();
            auto_zone_release(zone, (void*) cf);
        }
        else if (op == 0)
        {
            return currentCount;
        }
        
        return 0;
    }

    if (op == 0)
    {
        return currentCount;
    }
    else if (currentCount == 0)
    {
        // we may not be able to delete if the caller has active children
        if (obj->mayDelete())
        {
            finalizeType(cf);
            zap = true; // ask the caller to release the mutex and zap the object
            return 0;
        }
        else
        {
            return currentCount;
        }
    }
    else 
    {
        return 0;
    }
}