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); char *buffer = ((char*)region) + headerSize(gc_buffer_header);
if (scan) if (scan)
{ {
// FIXME: Implement GCAddBufferForTracing(region);
//GCTraceRegion(region);
} }
// Reference count is 0, so set visited to prevent it from being collected // Reference count is 0, so set visited to prevent it from being collected
// immediately // immediately

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

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

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

Loading…
Cancel
Save