Exemple #1
0
CFTypeRef CFMakeCollectable(CFTypeRef cf) {
    if (NULL == cf) return NULL;
    if (CF_IS_COLLECTABLE(cf)) {
#if defined(DEBUG)
        CFAllocatorRef allocator = CFGetAllocator(cf);
        if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
            CFLog(kCFLogLevelWarning, CFSTR("object %p with non-GC allocator %p passed to CFMakeCollectable."), cf, allocator);
            HALT;
        }
#endif
        if (!CFTYPE_IS_OBJC(cf)) {
            CFRuntimeClass *cfClass = __CFRuntimeClassTable[__CFGenericTypeID_inline(cf)];
            if (cfClass->version & (_kCFRuntimeResourcefulObject)) {
                // don't allow the collector to manage uncollectable objects.
                CFLog(kCFLogLevelWarning, CFSTR("uncollectable object %p passed to CFMakeCollectable."), cf);
                HALT;
            }
        }
        if (auto_zone_retain_count(__CFCollectableZone, cf) == 0) {
            CFLog(kCFLogLevelWarning, CFSTR("object %p with 0 retain-count passed to CFMakeCollectable."), cf);
            return cf;
        }
        auto_zone_release(__CFCollectableZone, (void *)cf);
    }
    return cf;
}
Exemple #2
0
CFIndex _CFGetRetainCount(CFTypeRef cf) {
    if (NULL == cf) return 0;
    if (CF_IS_COLLECTABLE(cf)) {
        return auto_zone_retain_count(__CFCollectableZone, cf);
    }
    uint64_t rc = __CFGetFullRetainCount(cf);
    return (rc < (uint64_t)LONG_MAX) ? (CFIndex)rc : (CFIndex)LONG_MAX;
}
Exemple #3
0
CFIndex CFGetRetainCount(CFTypeRef cf) {
    if (NULL == cf) return 0;
    if (CF_IS_COLLECTABLE(cf)) {
        return auto_zone_retain_count(__CFCollectableZone, cf);
    }
    CFTYPE_OBJC_FUNCDISPATCH0(CFIndex, cf, "retainCount");
    __CFGenericAssertIsCF(cf);
    uint64_t rc = __CFGetFullRetainCount(cf);
    return (rc < (uint64_t)LONG_MAX) ? (CFIndex)rc : (CFIndex)LONG_MAX;
}
Exemple #4
0
static void 
print_memory_object(task_t task, void *context, unsigned type_mask,
	vm_range_t *ranges, unsigned range_count)
{
    const size_t min_size = *(size_t *)context;
    for (vm_range_t *r = ranges, *end = ranges + range_count; r < end; r++) {
	const size_t size = auto_zone_size(__auto_zone, (void *)r->address);
	if (size >= min_size) {
	    printf("address %p size %ld rc %d layout type ",
		    (void *)r->address, size,
		    auto_zone_retain_count(__auto_zone, (void *)r->address));
	    switch (auto_zone_get_layout_type(__auto_zone,
			(void *)r->address)) {
		case AUTO_OBJECT:
		    printf("object (class %s)\n",
			    class_getName(object_getClass((void *)r->address)));
		    break;
		default:
		    printf("memory\n");
		    break;
	    }
	}
    }
}
Exemple #5
0
void
rb_node_release(NODE *node)
{
    if (node == NULL || node == (NODE *)-1) {
	return;
    }

//    static int c = 0;
//    printf("%d RELEASE %s %p\n", ++c, ruby_node_name(nd_type(node)), node);

    switch (nd_type(node)) {
	case NODE_IF:		/* 1,2,3 */
	case NODE_FOR:
	case NODE_ITER:
	case NODE_WHEN:
	case NODE_MASGN:
	case NODE_RESCUE:
	case NODE_RESBODY:
	case NODE_CLASS:
	case NODE_BLOCK_PASS:
	    rb_node_release(node->u2.node);
	    /* fall through */
	case NODE_BLOCK:	/* 1,3 */
	case NODE_OPTBLOCK:
	case NODE_ARRAY:
	case NODE_ENSURE:
	case NODE_CALL:
	case NODE_DEFS:
	case NODE_OP_ASGN1:
	case NODE_ARGS:
	    rb_node_release(node->u1.node);
	    /* fall through */
	case NODE_SUPER:	/* 3 */
	case NODE_FCALL:
	case NODE_DEFN:
	case NODE_ARGS_AUX:
	    rb_node_release(node->u3.node);
	    break;

	case NODE_WHILE:	/* 1,2 */
	case NODE_UNTIL:
	case NODE_AND:
	case NODE_OR:
	case NODE_CASE:
	case NODE_SCLASS:
	case NODE_DOT2:
	case NODE_DOT3:
	case NODE_FLIP2:
	case NODE_FLIP3:
	case NODE_MATCH2:
	case NODE_MATCH3:
	case NODE_OP_ASGN_OR:
	case NODE_OP_ASGN_AND:
	case NODE_MODULE:
	case NODE_ARGSCAT:
	    rb_node_release(node->u1.node);
	    /* fall through */
	case NODE_FBODY:	/* 2 */
	case NODE_GASGN:
	case NODE_LASGN:
	case NODE_DASGN:
	case NODE_DASGN_CURR:
	case NODE_IASGN:
	case NODE_IASGN2:
	case NODE_CVASGN:
	case NODE_OPT_N:
	case NODE_EVSTR:
	case NODE_UNDEF:
	case NODE_POSTEXE:
	    rb_node_release(node->u2.node);
	    break;

	case NODE_HASH:	/* 1 */
	case NODE_DEFINED:
	case NODE_RETURN:
	case NODE_BREAK:
	case NODE_NEXT:
	case NODE_YIELD:
	case NODE_COLON2:
	case NODE_SPLAT:
	case NODE_TO_ARY:
	    rb_node_release(node->u1.node);
	    break;

	case NODE_SCOPE:	/* 2,3 */
	case NODE_CDECL:
	case NODE_OPT_ARG:
	    rb_node_release(node->u3.node);
	    rb_node_release(node->u2.node);
	    break;
    }

//    c--;

    // Some NODE structures are apparently reused somewhere in parserland.
    const int count = auto_zone_retain_count(__auto_zone, node);
    if (count > 0) {
	node->u1.node = node->u2.node = node->u3.node = NULL;
	GC_RELEASE(node);
    }
}