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

@ -137,6 +137,24 @@ void doRefCountStuff(void)
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)
{
// Not required on main thread:
@ -147,4 +165,7 @@ int main(void)
doRefCountStuff();
GCDrain(YES);
sleep(2);
testTracedMemory();
buffer[0] = objc_assign_strongCast(nil, buffer);
GCDrain(YES);
}

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

@ -541,6 +541,7 @@ void GCRunTracer(void)
object->visitClearedGeneration < threadGeneration)
{
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
// for now.
GCSetFlag(obj, GCFlagVisited);
if (obj)
{
GCSetFlag(obj, GCFlagVisited);
}
pthread_rwlock_wrlock(&traced_objects_lock);
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
// 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);
if (new->pointer)
if (new)
{
new->heapAddress = ptr;
}
pthread_rwlock_unlock(&traced_objects_lock);
// Tracing semantics do not apply to objects with CF semantics, so skip the
// 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.
GCSetFlag(obj, GCFlagEscaped);

Loading…
Cancel
Save