From 4a9ad03cbd288a5451cadbf8f06684864d35888c Mon Sep 17 00:00:00 2001 From: Shaw Summa Date: Sat, 13 Jul 2024 17:06:07 -0400 Subject: [PATCH] auto gc - woo red commit --- .gitmodules | 8 +------- .vscode/settings.json | 3 ++- test/tables/trees.lua | 1 + vendor/bdwgc | 1 - vm/ast/ast.c | 14 -------------- vm/ast/ast.h | 1 - vm/backend/backend.c | 2 ++ vm/gc.c | 24 +++++++++++++++--------- vm/gc.h | 4 ++-- vm/obj.c | 26 +++++++++++++------------- vm/obj.h | 2 +- vm/save/read.c | 4 ++++ vm/std.c | 7 ++++--- vm/vm.c | 2 +- vm/vm.h | 2 ++ 15 files changed, 48 insertions(+), 53 deletions(-) delete mode 160000 vendor/bdwgc diff --git a/.gitmodules b/.gitmodules index d64efded..46190656 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,10 +6,4 @@ url = https://github.com/fastvm/minivm-isocline [submodule "vendor/raylib"] path = vendor/raylib - url = https://github.com/FastVM/minivm-raylib -[submodule "vendor/bdwgc"] - path = vendor/bdwgc - url = https://github.com/FastVM/minivm-bdwgc -[submodule "vendor/libatomic_ops"] - path = vendor/libatomic_ops - url = https://github.com/ivmai/libatomic_ops + url = https://github.com/FastVM/minivm-raylib \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index f5909b64..195ee266 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,7 @@ "files.associations": { "*.inc": "c", "*.c": "c", - "*.h": "c" + "*.h": "c", + "sstream": "c" } } \ No newline at end of file diff --git a/test/tables/trees.lua b/test/tables/trees.lua index e1b104fc..770266e3 100644 --- a/test/tables/trees.lua +++ b/test/tables/trees.lua @@ -50,6 +50,7 @@ while depth <= maxdepth do end print(depth, check) depth = depth + 2 + -- if vm then vm.gc() end end print(maxdepth, ItemCheck(longlivedtree)) diff --git a/vendor/bdwgc b/vendor/bdwgc deleted file mode 160000 index c0bc5423..00000000 --- a/vendor/bdwgc +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c0bc5423f4ab489640e151b943aa0e646a5d65f5 diff --git a/vm/ast/ast.c b/vm/ast/ast.c index 90c8578a..c77961d1 100644 --- a/vm/ast/ast.c +++ b/vm/ast/ast.c @@ -11,19 +11,6 @@ void vm_ast_free_ident(const char *ident) { vm_free(ident); } -void vm_ast_free_literal(vm_obj_t literal) { - switch (literal.tag) { - case VM_TAG_ERROR: { - // vm_free(literal.value.error.); - break; - } - case VM_TAG_STR: { - vm_free(literal.value.str); - break; - } - } -} - void vm_ast_free_node(vm_ast_node_t node) { switch (node.type) { case VM_AST_NODE_FORM: { @@ -35,7 +22,6 @@ void vm_ast_free_node(vm_ast_node_t node) { break; } case VM_AST_NODE_LITERAL: { - vm_ast_free_literal(node.value.literal); break; } } diff --git a/vm/ast/ast.h b/vm/ast/ast.h index 8e7475cd..10605b58 100644 --- a/vm/ast/ast.h +++ b/vm/ast/ast.h @@ -94,7 +94,6 @@ struct vm_ast_node_t { const char *vm_ast_format(vm_ast_node_t *node); void vm_ast_free_form(vm_ast_form_t node); void vm_ast_free_ident(const char *node); -void vm_ast_free_literal(vm_obj_t node); void vm_ast_free_node(vm_ast_node_t node); #endif \ No newline at end of file diff --git a/vm/backend/backend.c b/vm/backend/backend.c index 24acd305..80e3d2c4 100644 --- a/vm/backend/backend.c +++ b/vm/backend/backend.c @@ -2,6 +2,7 @@ #include "../vm.h" #include "../obj.h" #include "../ir.h" +#include "../gc.h" #define COMBINE(x, y) ((x)*VM_TAG_MAX + (y)) #define CONCAT_2(x, y) x ## _ ## y @@ -786,6 +787,7 @@ new_block_no_print:; .tag = VM_TAG_TAB, .value.table = vm_table_new(vm), })); + vm_gc_run(vm, regs + block->nregs); vm_run_repl_jump(); } VM_OP_TABLE_LEN:; VM_OPCODE_DEBUG(table_len) { diff --git a/vm/gc.c b/vm/gc.c index d295a70b..ce07c721 100644 --- a/vm/gc.c +++ b/vm/gc.c @@ -15,6 +15,7 @@ struct vm_gc_objs_t { }; struct vm_gc_t { + size_t last; vm_gc_objs_t objs; }; @@ -26,7 +27,7 @@ static void vm_gc_mark_obj(vm_obj_t obj) { } case VM_TAG_STR: { vm_io_buffer_t *buffer = obj.value.str; - if (buffer->mark == true) { + if (buffer->mark) { break; } buffer->mark = true; @@ -34,7 +35,7 @@ static void vm_gc_mark_obj(vm_obj_t obj) { } case VM_TAG_CLOSURE: { vm_closure_t *closure = obj.value.closure; - if (closure->mark == true) { + if (closure->mark) { break; } closure->mark = true; @@ -45,11 +46,11 @@ static void vm_gc_mark_obj(vm_obj_t obj) { } case VM_TAG_TAB: { vm_table_t *table = obj.value.table; - if (table->mark == true) { + if (table->mark) { break; } table->mark = true; - for (size_t i = 0; i < table->len; i++) { + for (size_t i = 0; i < (1 << table->alloc); i++) { vm_gc_mark_obj((vm_obj_t) { .tag = table->pairs[i].key_tag, .value = table->pairs[i].key_val, @@ -74,9 +75,9 @@ static void vm_gc_mark_arg(vm_arg_t arg) { } } -void vm_gc_mark(vm_t *vm) { +void vm_gc_mark(vm_t *vm, vm_obj_t *top) { vm_gc_mark_obj(vm->std); - for (vm_obj_t *head = vm->base; head != vm->regs; head++) { + for (vm_obj_t *head = vm->base; head < top; head++) { vm_gc_mark_obj(*head); } for (size_t i = 0; i < vm->blocks->len; i++) { @@ -145,12 +146,17 @@ void vm_gc_sweep(vm_t *vm) { gc->objs.objs[write++] = obj; } } - printf("%zu -> %zu\n", gc->objs.len, write); + // printf("%zu -> %zu\n", gc->objs.len, write); gc->objs.len = write; + gc->last = write; } -void vm_gc_run(vm_t *vm) { - vm_gc_mark(vm); +void vm_gc_run(vm_t *vm, vm_obj_t *top) { + vm_gc_t *gc = vm->gc; + if (gc->last * VM_GC_FACTOR >= gc->objs.len) { + return; + } + vm_gc_mark(vm, top); vm_gc_sweep(vm); } diff --git a/vm/gc.h b/vm/gc.h index 840a9e63..e33de378 100644 --- a/vm/gc.h +++ b/vm/gc.h @@ -3,10 +3,10 @@ #include "./lib.h" -void vm_gc_mark(vm_t *vm); +void vm_gc_mark(vm_t *vm, vm_obj_t *top); void vm_gc_sweep(vm_t *vm); -void vm_gc_run(vm_t *vm); +void vm_gc_run(vm_t *vm, vm_obj_t *top); void vm_gc_init(vm_t *vm); void vm_gc_deinit(vm_t *vm); diff --git a/vm/obj.c b/vm/obj.c index 8a9a034d..8a3e6e85 100644 --- a/vm/obj.c +++ b/vm/obj.c @@ -417,19 +417,7 @@ void vm_table_set(vm_table_t *restrict table, vm_value_t key_val, vm_value_t val next += 1; next &= and; } while (next != stop); - if ((table->used + 1) * 100 >= ((uint32_t)1 << table->alloc) * 76) { - vm_table_t ret; - vm_table_init_size(&ret, table->alloc + 1); - for (size_t i = 0; i < len; i++) { - vm_table_pair_t *in_pair = &table->pairs[i]; - if (in_pair->key_tag != VM_TAG_UNK && in_pair->key_tag != VM_TAG_NIL) { - vm_table_set_pair(&ret, in_pair); - } - } - vm_table_set(&ret, key_val, val_val, key_tag, val_tag); - vm_free(table->pairs); - *table = ret; - } else if (val_tag == VM_TAG_NIL) { + if (val_tag == VM_TAG_NIL) { table->pairs[next] = (vm_table_pair_t){ .key_tag = key_tag, .key_val = key_val, @@ -447,6 +435,18 @@ void vm_table_set(vm_table_t *restrict table, vm_value_t key_val, vm_value_t val if (1 <= n && n <= table->len && (double) (size_t) n == n) { table->len = (size_t) (n - 1); } + } else if ((table->used + 1) * 100 >= ((uint32_t)1 << table->alloc) * 76) { + vm_table_t ret; + vm_table_init_size(&ret, table->alloc + 1); + for (size_t i = 0; i < len; i++) { + vm_table_pair_t *in_pair = &table->pairs[i]; + if (in_pair->key_tag != VM_TAG_UNK && in_pair->key_tag != VM_TAG_NIL) { + vm_table_set_pair(&ret, in_pair); + } + } + vm_table_set(&ret, key_val, val_val, key_tag, val_tag); + vm_free(table->pairs); + *table = ret; } else { table->used += 1; table->pairs[next] = (vm_table_pair_t){ diff --git a/vm/obj.h b/vm/obj.h index 9cb85631..525144fc 100644 --- a/vm/obj.h +++ b/vm/obj.h @@ -91,6 +91,6 @@ void vm_table_get_pair(vm_table_t *table, vm_table_pair_t *pair); vm_table_set(table_, key_.value, value_.value, key_.tag, value_.tag); \ }) -#define VM_TABLE_LOOKUP_STR(TABLE_, STR_) (vm_table_lookup((TABLE_), (vm_value_t){.str = (STR_)}, VM_TAG_STR)) +#define VM_TABLE_LOOKUP_STR(TABLE_, STR_) (vm_table_lookup((TABLE_), (vm_value_t){.str = vm_io_buffer_from_str(STR_)}, VM_TAG_STR)) #endif diff --git a/vm/save/read.c b/vm/save/read.c index a84c9e5e..a5ae392d 100644 --- a/vm/save/read.c +++ b/vm/save/read.c @@ -129,6 +129,10 @@ void vm_load_value(vm_t *vm, vm_save_t save) { vm_io_buffer_format(buf, "%c", vm_save_read_byte(&read)); } value.str = buf; + vm_gc_add(vm, (vm_obj_t) { + .tag = tag, + .value = value, + }); break; } case VM_TAG_FFI: { diff --git a/vm/std.c b/vm/std.c index ba04ce90..5168f347 100644 --- a/vm/std.c +++ b/vm/std.c @@ -96,7 +96,7 @@ void vm_std_error(vm_t *vm, vm_obj_t *args) { if (args[0].tag == VM_TAG_STR) { *args = (vm_obj_t){ .tag = VM_TAG_ERROR, - .value.str = args[0].value.str, + .value.error = vm_error_from_msg(vm_location_range_unknown, args[0].value.str->buf), }; return; } @@ -135,7 +135,8 @@ void vm_std_vm_closure(vm_t *vm, vm_obj_t *args) { } void vm_std_vm_gc(vm_t *vm, vm_obj_t *args) { - vm_gc_run(vm); + vm_gc_run(vm, vm->regs); + *args = VM_OBJ_NIL; } void vm_std_vm_print(vm_t *vm, vm_obj_t *args) { @@ -1036,7 +1037,7 @@ void vm_std_new(vm_t *vm) { VM_TABLE_SET(tvm, str, vm_str(vm, "import").value.str, ffi, VM_STD_REF(vm, vm_std_vm_import)); VM_TABLE_SET(tvm, str, vm_str(vm, "gc").value.str, ffi, VM_STD_REF(vm, vm_std_vm_gc)); VM_TABLE_SET(tvm, str, vm_str(vm, "print").value.str, ffi, VM_STD_REF(vm, vm_std_vm_print)); - VM_TABLE_SET(tvm, str, vm_str(vm, "version").value.str, str, vm_str(vm, "0.0.4").value.str); + VM_TABLE_SET(tvm, str, vm_str(vm, "version").value.str, str, vm_str(vm, "0.0.5").value.str); VM_TABLE_SET(tvm, str, vm_str(vm, "typename").value.str, ffi, VM_STD_REF(vm, vm_std_vm_typename)); VM_TABLE_SET(tvm, str, vm_str(vm, "typeof").value.str, ffi, VM_STD_REF(vm, vm_std_vm_typeof)); VM_TABLE_SET(tvm, str, vm_str(vm, "concat").value.str, ffi, VM_STD_REF(vm, vm_std_vm_concat)); diff --git a/vm/vm.c b/vm/vm.c index b834938f..fe318fb1 100644 --- a/vm/vm.c +++ b/vm/vm.c @@ -8,7 +8,7 @@ #include "./gc.h" vm_t *vm_state_new(void) { - vm_obj_t *base = vm_malloc(sizeof(vm_obj_t) * 65536); + vm_obj_t *base = vm_malloc(sizeof(vm_obj_t) * (1 << 20)); vm_t *vm = vm_malloc(sizeof(vm_t)); *vm = (vm_t) { .use_num = VM_USE_NUM_F64, diff --git a/vm/vm.h b/vm/vm.h index 4df461b0..90881aa7 100644 --- a/vm/vm.h +++ b/vm/vm.h @@ -6,6 +6,8 @@ #include #include +// #define VM_GC_FACTOR 1.03659 +#define VM_GC_FACTOR 1.25 #define VM_FORMAT_FLOAT "%.14g" struct vm_t;