Added out-of-tree GCKit stuff. Still (very) work-in-progress.

main
theraven 16 years ago
parent 7b535dcda4
commit ce5b0e9f83

@ -92,8 +92,7 @@ void *GCAllocateBufferWithZone(void *zone, size_t size, BOOL scan)
char *buffer = ((char*)region) + headerSize(gc_buffer_header);
if (scan)
{
// FIXME: Implement
//GCTraceRegion(region);
GCAddBufferForTracing(region);
}
// Reference count is 0, so set visited to prevent it from being collected
// immediately

@ -159,6 +159,7 @@ void putObjectInBuffer(void)
{
buffer = (id*)GCRetain((id)GCAllocateBufferWithZone(NULL, sizeof(id), YES));
buffer[0] = objc_assign_strongCast([SimpleObject new], buffer);
//fprintf(stderr, "Storing pointer %x in traced memory %x\n", (int)buffer[0], (int)buffer);
[*buffer log];
GCDrain(YES);
GCDrain(YES);
@ -205,10 +206,10 @@ void makeTracedCycle(void)
Pair *p = [Pair new];
id *b2 = GCAllocateBufferWithZone(NULL, sizeof(id), YES);
fprintf(stderr, "Expected to leak %x and %x\n", (int)b1, (int)b2);
//objc_assign_strongCast((id)b2, b1);
objc_assign_strongCast(p, b1);
objc_assign_strongCast((id)b2, b1);
//objc_assign_strongCast(p, b1);
objc_assign_strongCast((id)b1, b2);
p->a = (id)b2;
p->a = GCRetain((id)b2);
}
void testTracedCycle(void)
@ -219,6 +220,7 @@ void testTracedCycle(void)
int main(void)
{
testTracedCycle();
/*
// Not required on main thread:
//GCRegisterThread();
doStuff();
@ -230,6 +232,7 @@ int main(void)
GCDrain(YES);
testCycle();
*/
GCDrain(YES);
GCDrain(YES);
GCDrain(YES);

@ -14,6 +14,9 @@ void GCRunTracerIfNeeded(BOOL);
void GCAddObjectsForTracing(GCThread *thr);
void GCTraceStackSynchronous(GCThread *thr);
void GCAddBufferForTracing(struct gc_buffer_header *buffer);
extern volatile int GCGeneration;
void GCCollect();
id objc_assign_strongCast(id obj, id *ptr);

@ -15,6 +15,7 @@
#import "cycle.h"
#import "malloc.h"
#import "static.h"
#import "workqueue.h"
/**
* Structure storing pointers that are currently being traced.
@ -212,13 +213,13 @@ static int debugTree(GCTracedRegionTreeNode *node)
}
/* Invalid binary search tree */
assert(left != NULL || (GCCompareRegions(left->region, node->region) < 0));
assert(right != NULL || (GCCompareRegions(right->region, node->region) > 0));
assert(left == NULL || (GCCompareRegions(left->region, node->region) < 0));
assert(right == NULL || (GCCompareRegions(right->region, node->region) > 0));
int leftHeight = debugTree(left);
int rightHeight = debugTree(right);
assert(leftHeight == 0 || rightHeight ==0 || leftHeight == rightHeight);
//assert(leftHeight == 0 || rightHeight ==0 || leftHeight == rightHeight);
/* Only count black children */
if (leftHeight != 0 && rightHeight != 0)
@ -283,7 +284,7 @@ static GCTracedRegionTreeNode *tracedRegionInsert(
__attribute__((unused))
static void GCTracedRegionInsert(GCTracedRegion region)
{
tracedRegionInsert(GCRegionTreeRoot, region);
GCRegionTreeRoot = tracedRegionInsert(GCRegionTreeRoot, region);
GCRegionTreeRoot->colour = BLACK;
debugTree(GCRegionTreeRoot);
}
@ -427,6 +428,7 @@ static void GCTraceRegion(GCTracedRegion region, void *c)
// Stop if we've already found references to everything that might be
// garbage.
id *object = region.start;
fprintf(stderr, "Region starts at %x (%d bytes)\n", (int)object, (int)region.end - (int)region.start);
while (object < (id*)region.end)
{
if (context->foundObjects == traced_objects->table_used)
@ -434,14 +436,16 @@ static void GCTraceRegion(GCTracedRegion region, void *c)
return;
}
GCTracedPointer *foundObject = traced_object_table_get(traced_objects, *object);
if (foundObject->pointer)
if (foundObject && foundObject->pointer)
{
//fprintf(stderr, "Found traced heap pointer to %x\n", (int)foundObject->pointer);
if(!GCTestFlag(foundObject->pointer, GCFlagVisited))
{
context->foundObjects++;
GCSetFlag(foundObject->pointer, GCFlagVisited);
}
}
object++;
}
}
/**
@ -677,6 +681,20 @@ void GCAddObjectsForTracing(GCThread *thr)
pthread_rwlock_unlock(&traced_objects_lock);
}
static void GCAddBufferForTracingTrampoline(void *b)
{
struct gc_buffer_header *buffer = b;
GCTracedRegion region = { buffer, (char*)buffer + sizeof(struct gc_buffer_header),
(char*)buffer + sizeof(struct gc_buffer_header) + buffer->size };
fprintf(stderr, "Buffer has size %d (%d)\n", buffer->size, (int)region.end - (int)region.start);
GCTracedRegionInsert(region);
}
void GCAddBufferForTracing(struct gc_buffer_header *buffer)
{
GCPerform(GCAddBufferForTracingTrampoline, buffer);
}
// TODO: memmove_collectable does this for a whole region, but only does the
// locking once.
id objc_assign_strongCast(id obj, id *ptr)

Loading…
Cancel
Save