diff options
Diffstat (limited to 'runtime/GC')
-rw-r--r-- | runtime/GC/SemiSpace/semispace.c | 98 |
1 files changed, 61 insertions, 37 deletions
diff --git a/runtime/GC/SemiSpace/semispace.c b/runtime/GC/SemiSpace/semispace.c index 93327ed..a005a48 100644 --- a/runtime/GC/SemiSpace/semispace.c +++ b/runtime/GC/SemiSpace/semispace.c @@ -18,37 +18,7 @@ #include "../GCInterface.h" #include <stdio.h> #include <stdlib.h> - -/* FIXME: This should be in a code-generator specific library! - */ -typedef struct GCRoot { - void **RootPtr; - void *Meta; -} GCRoot; - -typedef struct GCRoots { - struct GCRoots *Next; - unsigned NumRoots; - GCRoot RootRecords[]; -} GCRoots; -GCRoots *llvm_gc_root_chain; - -static void llvm_cg_walk_gcroots(void (*FP)(void **Root, void *Meta)) { - GCRoots *R = llvm_gc_root_chain; - for (; R; R = R->Next) { - unsigned i, e; - for (i = 0, e = R->NumRoots; i != e; ++i) - FP(R->RootRecords[i].RootPtr, R->RootRecords[i].Meta); - } -} -/* END FIXME! */ - - - -/* We use no read/write barriers */ -void *llvm_gc_read(void **P) { return *P; } -void llvm_gc_write(void *V, void **P) { *P = V; } - +#include <string.h> /* AllocPtr - This points to the next byte that is available for allocation. */ @@ -59,9 +29,22 @@ static char *AllocPtr; */ static char *AllocEnd; -void llvm_gc_initialize() { - AllocPtr = calloc(1, 1000); - AllocEnd = AllocPtr + 1000; +/* CurSpace/OtherSpace - These pointers point to the two regions of memory that + * we switch between. The unallocated portion of the CurSpace is known to be + * zero'd out, but the OtherSpace contains junk. + */ +static void *CurSpace, *OtherSpace; + +/* SpaceSize - The size of each space. */ +static unsigned SpaceSize; + +/* llvm_gc_initialize - Allocate the two spaces that we plan to switch between. + */ +void llvm_gc_initialize(unsigned InitialHeapSize) { + SpaceSize = InitialHeapSize/2; + CurSpace = AllocPtr = calloc(1, SpaceSize); + OtherSpace = malloc(SpaceSize); + AllocEnd = AllocPtr + SpaceSize; } /* We always want to inline the fast path, but never want to inline the slow @@ -81,18 +64,59 @@ void *llvm_gc_allocate(unsigned Size) { static void* llvm_gc_alloc_slow(unsigned Size) { llvm_gc_collect(); + if (AllocPtr+Size > AllocEnd) { + fprintf(stderr, "Garbage collector ran out of memory " + "allocating object of size: %d\n", Size); + exit(1); + } + return llvm_gc_allocate(Size); } -static void process_root(void **Root, void *Meta) { +static void process_pointer(void **Root, void *Meta) { printf("process_root[0x%X] = 0x%X\n", (unsigned) Root, (unsigned) *Root); } void llvm_gc_collect() { + // Clear out the space we will be copying into. + // FIXME: This should do the copy, then clear out whatever space is left. + memset(OtherSpace, 0, SpaceSize); + printf("Garbage collecting!!\n"); - llvm_cg_walk_gcroots(process_root); + llvm_cg_walk_gcroots(process_pointer); abort(); +} + +/* We use no read/write barriers */ +void *llvm_gc_read(void **P) { return *P; } +void llvm_gc_write(void *V, void **P) { *P = V; } + + +/*===----------------------------------------------------------------------===** + * FIXME: This should be in a code-generator specific library, but for now this + * will work for all code generators. + */ +typedef struct GCRoot { + void **RootPtr; + void *Meta; +} GCRoot; - /* TODO: Iterate through roots. */ +typedef struct GCRoots { + struct GCRoots *Next; + unsigned NumRoots; + GCRoot RootRecords[]; +} GCRoots; +GCRoots *llvm_gc_root_chain; + +void llvm_cg_walk_gcroots(void (*FP)(void **Root, void *Meta)) { + GCRoots *R = llvm_gc_root_chain; + for (; R; R = R->Next) { + unsigned i, e; + for (i = 0, e = R->NumRoots; i != e; ++i) + FP(R->RootRecords[i].RootPtr, R->RootRecords[i].Meta); + } } +/* END FIXME! */ + + |