Some memory management fixes to the blocks runtime.

main
theraven 15 years ago
parent 4e3cacf997
commit caa4a7253c

@ -72,7 +72,7 @@ enum block_flags
* 3 bytes are reserved for the reference count, the top byte for the * 3 bytes are reserved for the reference count, the top byte for the
* flags. * flags.
*/ */
BLOCK_REFCOUNT_MASK = 0x00ffffffff BLOCK_REFCOUNT_MASK = 0x00ffffff
}; };
/** /**
@ -102,6 +102,7 @@ enum
BLOCK_BYREF_CALLER = 128, // called from byref copy/dispose helpers BLOCK_BYREF_CALLER = 128, // called from byref copy/dispose helpers
}; };
#define IS_SET(x, y) ((x & y) == y)
/** /**
* Block descriptor that contains copy and dispose operations. * Block descriptor that contains copy and dispose operations.
@ -283,10 +284,16 @@ void _Block_object_assign(void *destAddr, const void *object, const int flags)
} }
//else //else
{ {
fprintf(stderr, "BLOCK_FIELD_IS_OBJECT: %d\n", (flags & BLOCK_FIELD_IS_OBJECT) == BLOCK_FIELD_IS_OBJECT);
fprintf(stderr, "BLOCK_FIELD_IS_BLOCK: %d\n", (flags & BLOCK_FIELD_IS_BLOCK) == BLOCK_FIELD_IS_BLOCK);
fprintf(stderr, "BLOCK_FIELD_IS_BYREF: %d\n", (flags & BLOCK_FIELD_IS_BYREF) == BLOCK_FIELD_IS_BYREF);
fprintf(stderr, "BLOCK_FIELD_IS_WEAK: %d\n", (flags & BLOCK_FIELD_IS_WEAK) == BLOCK_FIELD_IS_WEAK);
if(flags & BLOCK_FIELD_IS_BYREF) if(flags & BLOCK_FIELD_IS_BYREF)
{ {
struct block_byref_obj *src = (struct block_byref_obj *)object; struct block_byref_obj *src = (struct block_byref_obj *)object;
struct block_byref_obj **dst = destAddr; struct block_byref_obj **dst = destAddr;
fprintf(stderr, "Copy dispose? %d\n", (src->flags & BLOCK_HAS_COPY_DISPOSE) == BLOCK_HAS_COPY_DISPOSE);
fprintf(stderr, "Retain Count? %x %x\n", src->flags & BLOCK_REFCOUNT_MASK, BLOCK_REFCOUNT_MASK);
if ((src->flags & BLOCK_REFCOUNT_MASK) == 0) if ((src->flags & BLOCK_REFCOUNT_MASK) == 0)
{ {
@ -310,7 +317,6 @@ void _Block_object_assign(void *destAddr, const void *object, const int flags)
// it. If the forwarding pointer in src has changed, then we // it. If the forwarding pointer in src has changed, then we
// recover - clean up and then return the structure that the // recover - clean up and then return the structure that the
// other thread created. // other thread created.
/*
if (!__sync_bool_compare_and_swap(&src->forwarding, src, *dst)) if (!__sync_bool_compare_and_swap(&src->forwarding, src, *dst))
{ {
if((size_t)src->size >= sizeof(struct block_byref_obj)) if((size_t)src->size >= sizeof(struct block_byref_obj))
@ -320,14 +326,13 @@ void _Block_object_assign(void *destAddr, const void *object, const int flags)
free(*dst); free(*dst);
*dst = src->forwarding; *dst = src->forwarding;
} }
*/
} }
else else
{ {
*dst = (struct block_byref_obj*)src; *dst = (struct block_byref_obj*)src;
}
increment24(&(*dst)->flags); increment24(&(*dst)->flags);
fprintf(stderr, "Flags for block: %p: %d\n", *dst, (*dst)->flags); fprintf(stderr, "Flags for block: %p: %d (refcount %x)\n", *dst, (*dst)->flags, (*dst)->flags & BLOCK_REFCOUNT_MASK);
}
} }
else if((flags & BLOCK_FIELD_IS_BLOCK) == BLOCK_FIELD_IS_BLOCK) else if((flags & BLOCK_FIELD_IS_BLOCK) == BLOCK_FIELD_IS_BLOCK)
{ {
@ -336,7 +341,7 @@ void _Block_object_assign(void *destAddr, const void *object, const int flags)
*dst = Block_copy(src); *dst = Block_copy(src);
} }
else if((flags & BLOCK_FIELD_IS_OBJECT) == BLOCK_FIELD_IS_OBJECT) else if ((flags & BLOCK_FIELD_IS_OBJECT) == BLOCK_FIELD_IS_OBJECT)
{ {
fprintf(stderr, "-retain\n"); fprintf(stderr, "-retain\n");
id src = (id)object; id src = (id)object;
@ -355,6 +360,10 @@ void _Block_object_assign(void *destAddr, const void *object, const int flags)
void _Block_object_dispose(const void *object, const int flags) void _Block_object_dispose(const void *object, const int flags)
{ {
fprintf(stderr, "Dispose %p, Flags: %d\n", object, flags); fprintf(stderr, "Dispose %p, Flags: %d\n", object, flags);
fprintf(stderr, "BLOCK_FIELD_IS_OBJECT: %d\n", (flags & BLOCK_FIELD_IS_OBJECT) == BLOCK_FIELD_IS_OBJECT);
fprintf(stderr, "BLOCK_FIELD_IS_BLOCK: %d\n", (flags & BLOCK_FIELD_IS_BLOCK) == BLOCK_FIELD_IS_BLOCK);
fprintf(stderr, "BLOCK_FIELD_IS_BYREF: %d\n", (flags & BLOCK_FIELD_IS_BYREF) == BLOCK_FIELD_IS_BYREF);
fprintf(stderr, "BLOCK_FIELD_IS_WEAK: %d\n", (flags & BLOCK_FIELD_IS_WEAK) == BLOCK_FIELD_IS_WEAK);
// FIXME: Needs to be implemented // FIXME: Needs to be implemented
//if(flags & BLOCK_FIELD_IS_WEAK) //if(flags & BLOCK_FIELD_IS_WEAK)
{ {
@ -367,8 +376,9 @@ void _Block_object_dispose(const void *object, const int flags)
(struct block_byref_obj*)object; (struct block_byref_obj*)object;
if (src->isa == _HeapBlockByRef) if (src->isa == _HeapBlockByRef)
{ {
fprintf(stderr, "refcount %d\n", src->flags); fprintf(stderr, "refcount %x\n", src->flags & BLOCK_REFCOUNT_MASK);
int refcount = decrement24(&src->flags); int refcount = (src->flags & BLOCK_REFCOUNT_MASK) == 0 ? 0 : decrement24(&src->flags);
fprintf(stderr, "new refcount %x\n", refcount & BLOCK_REFCOUNT_MASK);
if (refcount == 0) if (refcount == 0)
{ {
if (0 != src->byref_dispose) if (0 != src->byref_dispose)
@ -383,15 +393,12 @@ void _Block_object_dispose(const void *object, const int flags)
fprintf(stderr, "src: %p\n", src); fprintf(stderr, "src: %p\n", src);
fprintf(stderr, "forwarding: %p\n", src->forwarding); fprintf(stderr, "forwarding: %p\n", src->forwarding);
fprintf(stderr, "dispose: %p\n", src->byref_dispose); fprintf(stderr, "dispose: %p\n", src->byref_dispose);
//void *var = src+1; fprintf(stderr, "Cleaning up %p\n" , *(id*)(src+1));
//id obj = *(id*)var;
fprintf(stderr, "Cleaning up %p\n" ,obj);
// Call nontrivial destructors, but don't // Call nontrivial destructors, but don't
if (0 != src->byref_dispose) if (0 != src->byref_dispose)
{ {
//fprintf(stderr, "Calling byref dispose\n"); //fprintf(stderr, "Calling byref dispose\n");
//src->byref_dispose(src); src->byref_dispose(src);
//src->byref_dispose(0);
//fprintf(stderr, "Called byref dispose\n"); //fprintf(stderr, "Called byref dispose\n");
} }
// If this block has been promoted to the heap, decrement its // If this block has been promoted to the heap, decrement its

Loading…
Cancel
Save