From 2ff8acbe1afff28cb152c1a306971c8c57d03c94 Mon Sep 17 00:00:00 2001 From: Bob Nystrom Date: Thu, 29 Oct 2015 07:38:09 -0700 Subject: [PATCH] Tweak a few things in the new GC. - Make sure it handles an empty gray set. - Make sure growing the gray stack doesn't itself trigger a GC. - Make sure it works when stress testing is enabled. - Ensure the tests kick off a GC. --- src/vm/wren_value.c | 17 ++++++++--------- src/vm/wren_vm.c | 18 +++++++----------- src/vm/wren_vm.h | 4 ++-- test/language/deeply_nested_gc.wren | 3 ++- test/language/many_reallocations.wren | 4 +++- 5 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/vm/wren_value.c b/src/vm/wren_value.c index 0f3b0b2a..58f44588 100644 --- a/src/vm/wren_value.c +++ b/src/vm/wren_value.c @@ -867,15 +867,14 @@ void wrenGrayObj(WrenVM* vm, Obj* obj) // Add it to the gray list so it can be recursively explored for // more marks later. - if (vm->grayDepth >= vm->maxGray) + if (vm->grayCount >= vm->grayCapacity) { - size_t oldSize = vm->maxGray * sizeof(Obj*); - size_t newSize = vm->grayDepth * 2 * sizeof(Obj*); - vm->gray = (Obj**)wrenReallocate(vm, vm->gray, oldSize, newSize); - vm->maxGray = vm->grayDepth * 2; + vm->grayCapacity = vm->grayCount * 2; + vm->gray = vm->config.reallocateFn(vm->gray, + vm->grayCapacity * sizeof(Obj*)); } - vm->gray[vm->grayDepth++] = obj; + vm->gray[vm->grayCount++] = obj; } void wrenGrayValue(WrenVM* vm, Value value) @@ -1095,12 +1094,12 @@ static void blackenObject(WrenVM* vm, Obj* obj) void wrenBlackenObjects(WrenVM* vm) { - do + while (vm->grayCount > 0) { // Pop an item from the gray stack. - Obj* obj = vm->gray[--vm->grayDepth]; + Obj* obj = vm->gray[--vm->grayCount]; blackenObject(vm, obj); - } while (vm->grayDepth > 0); + } } void wrenFreeObj(WrenVM* vm, Obj* obj) diff --git a/src/vm/wren_vm.c b/src/vm/wren_vm.c index 0ef7f108..de3e1a6e 100644 --- a/src/vm/wren_vm.c +++ b/src/vm/wren_vm.c @@ -46,29 +46,25 @@ void wrenInitConfiguration(WrenConfiguration* config) config->heapGrowthPercent = 50; } -static void initializeGC(WrenVM* vm) -{ - vm->gray = (Obj**)wrenReallocate(vm, NULL, 0, 5 * sizeof(Obj*)); - vm->grayDepth = 0; - vm->maxGray = 5; -} - WrenVM* wrenNewVM(WrenConfiguration* config) { WrenVM* vm = (WrenVM*)config->reallocateFn(NULL, sizeof(*vm)); memset(vm, 0, sizeof(WrenVM)); memcpy(&vm->config, config, sizeof(WrenConfiguration)); + // TODO: Should we allocate and free this during a GC? + vm->grayCount = 0; + // TODO: Tune this. + vm->grayCapacity = 4; + vm->gray = vm->config.reallocateFn(NULL, vm->grayCapacity * sizeof(Obj*)); vm->nextGC = config->initialHeapSize; - + wrenSymbolTableInit(&vm->methodNames); vm->modules = wrenNewMap(vm); wrenInitializeCore(vm); - initializeGC(vm); - // TODO: Lazy load these. #if WREN_OPT_META wrenLoadMetaModule(vm); @@ -94,7 +90,7 @@ void wrenFreeVM(WrenVM* vm) } // Free up the GC gray set. - wrenReallocate(vm, vm->gray, vm->maxGray * sizeof(Obj*), 0); + vm->gray = vm->config.reallocateFn(vm->gray, 0); // Tell the user if they didn't free any handles. We don't want to just free // them here because the host app may still have pointers to them that they diff --git a/src/vm/wren_vm.h b/src/vm/wren_vm.h index 3c0ec5c1..9b613a80 100644 --- a/src/vm/wren_vm.h +++ b/src/vm/wren_vm.h @@ -72,8 +72,8 @@ struct WrenVM // The "gray" set for the garbage collector. This is the stack of unprocessed // objects while a garbage collection pass is in process. Obj** gray; - int grayDepth; - int maxGray; + int grayCount; + int grayCapacity; // The list of temporary roots. This is for temporary or new objects that are // not otherwise reachable but should not be collected. diff --git a/test/language/deeply_nested_gc.wren b/test/language/deeply_nested_gc.wren index c40fa4c7..04bd443c 100644 --- a/test/language/deeply_nested_gc.wren +++ b/test/language/deeply_nested_gc.wren @@ -4,4 +4,5 @@ for (i in 1..400000) { head = { "next" : head } } -System.print("done") // expect: done \ No newline at end of file +System.gc() +System.print("done") // expect: done diff --git a/test/language/many_reallocations.wren b/test/language/many_reallocations.wren index 06a96285..cb9b28d5 100644 --- a/test/language/many_reallocations.wren +++ b/test/language/many_reallocations.wren @@ -10,5 +10,7 @@ for (i in 1..1000) { } found.add(bar) } + +System.gc() System.print(found.all {|i| i == 1337}) // expect: true -System.print("DONE!") // expect: DONE! +System.print("done") // expect: done