Added test for strong-cast assign (assign to traced memory allocated with GCAllocateCollectable()). Fixed bugs that it showed.

main
theraven 16 years ago
parent 5b1911b4f4
commit 1f1c5b5b1a

@ -7,6 +7,7 @@
#import "visit.h" #import "visit.h"
#import "workqueue.h" #import "workqueue.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
@interface GCObject @interface GCObject
- (void)finalize; - (void)finalize;
@ -135,6 +136,7 @@ void GCFreeObjectUnsafe(id object)
// finalize it. // finalize it.
if (!GCTestFlag(object, GCFlagNotObject)) if (!GCTestFlag(object, GCFlagNotObject))
{ {
fprintf(stderr, "Finalizing object %x\n", (int)(object));
GCVisitChildren(object, releaseObjects, NULL, YES); GCVisitChildren(object, releaseObjects, NULL, YES);
[object finalize]; [object finalize];
region.end += class_getInstanceSize(object->isa); region.end += class_getInstanceSize(object->isa);
@ -148,6 +150,7 @@ void GCFreeObjectUnsafe(id object)
} }
if (GCGetWeakRefCount(object) == 0) if (GCGetWeakRefCount(object) == 0)
{ {
fprintf(stderr, "Freeing object %x\n", (int)(object));
gc_free_with_zone(GCHeaderForObject(object)->zone, object); gc_free_with_zone(GCHeaderForObject(object)->zone, object);
} }
} }

@ -137,6 +137,24 @@ void doRefCountStuff(void)
makeRefCountedObject(); makeRefCountedObject();
} }
static id *buffer;
void putObjectInBuffer(void)
{
buffer = GCAllocateBufferWithZone(NULL, sizeof(id), YES);
buffer[0] = objc_assign_strongCast([SimpleObject new], buffer);
[*buffer log];
GCDrain(YES);
GCDrain(YES);
sleep(1);
}
void testTracedMemory(void)
{
putObjectInBuffer();
GCDrain(YES);
}
int main(void) int main(void)
{ {
// Not required on main thread: // Not required on main thread:
@ -147,4 +165,7 @@ int main(void)
doRefCountStuff(); doRefCountStuff();
GCDrain(YES); GCDrain(YES);
sleep(2); sleep(2);
testTracedMemory();
buffer[0] = objc_assign_strongCast(nil, buffer);
GCDrain(YES);
} }

@ -15,3 +15,4 @@ void GCTraceStackSynchronous(GCThread *thr);
extern volatile int GCGeneration; extern volatile int GCGeneration;
void GCCollect(); void GCCollect();
id objc_assign_strongCast(id obj, id *ptr);

@ -541,6 +541,7 @@ void GCRunTracer(void)
object->visitClearedGeneration < threadGeneration) object->visitClearedGeneration < threadGeneration)
{ {
GCFreeObjectUnsafe(object->pointer); GCFreeObjectUnsafe(object->pointer);
traced_object_remove(traced_objects, object->pointer);
} }
} }
} }
@ -631,10 +632,13 @@ id objc_assign_strongCast(id obj, id *ptr)
{ {
// This object is definitely stored somewhere, so mark it as visited // This object is definitely stored somewhere, so mark it as visited
// for now. // for now.
GCSetFlag(obj, GCFlagVisited); if (obj)
{
GCSetFlag(obj, GCFlagVisited);
}
pthread_rwlock_wrlock(&traced_objects_lock); pthread_rwlock_wrlock(&traced_objects_lock);
GCTracedPointer *old = traced_object_table_get(traced_objects, *ptr); GCTracedPointer *old = traced_object_table_get(traced_objects, *ptr);
if (old->pointer) if (old)
{ {
// If the value that we are overwriting is a traced pointer and this is // If the value that we are overwriting is a traced pointer and this is
// the pointer to it that we are tracking then mark it as not visited. // the pointer to it that we are tracking then mark it as not visited.
@ -649,14 +653,14 @@ id objc_assign_strongCast(id obj, id *ptr)
} }
} }
GCTracedPointer *new = traced_object_table_get(traced_objects, obj); GCTracedPointer *new = traced_object_table_get(traced_objects, obj);
if (new->pointer) if (new)
{ {
new->heapAddress = ptr; new->heapAddress = ptr;
} }
pthread_rwlock_unlock(&traced_objects_lock); pthread_rwlock_unlock(&traced_objects_lock);
// Tracing semantics do not apply to objects with CF semantics, so skip the // Tracing semantics do not apply to objects with CF semantics, so skip the
// next bits if the CF flag is set. // next bits if the CF flag is set.
if (!GCTestFlag(obj, GCFlagCFObject)) if (obj && !GCTestFlag(obj, GCFlagCFObject))
{ {
// Don't free this just after scanning the stack. // Don't free this just after scanning the stack.
GCSetFlag(obj, GCFlagEscaped); GCSetFlag(obj, GCFlagEscaped);

Loading…
Cancel
Save