1
0
mirror of https://github.com/janet-lang/janet synced 2024-11-25 09:47:17 +00:00

Merge code back from correctgc.

This commit is contained in:
Calvin Rose 2018-09-23 17:53:55 -04:00
parent a92893482b
commit 9b579c9ce6
3 changed files with 40 additions and 29 deletions

View File

@ -31,11 +31,10 @@ JANET_THREAD_LOCAL uint32_t janet_vm_gc_interval;
JANET_THREAD_LOCAL uint32_t janet_vm_next_collection; JANET_THREAD_LOCAL uint32_t janet_vm_next_collection;
JANET_THREAD_LOCAL int janet_vm_gc_suspend = 0; JANET_THREAD_LOCAL int janet_vm_gc_suspend = 0;
/* GC mark state */ /* Roots */
JANET_THREAD_LOCAL Janet *janet_vm_gc_marklist = NULL; JANET_THREAD_LOCAL Janet *janet_vm_roots;
JANET_THREAD_LOCAL size_t janet_vm_gc_marklist_count = 0; JANET_THREAD_LOCAL uint32_t janet_vm_root_count;
JANET_THREAD_LOCAL size_t janet_vm_gc_marklist_capacity = 0; JANET_THREAD_LOCAL uint32_t janet_vm_root_capacity;
JANET_THREAD_LOCAL size_t janet_vm_gc_marklist_rootcount = 0;
/* Helpers for marking the various gc types */ /* Helpers for marking the various gc types */
static void janet_mark_funcenv(JanetFuncEnv *env); static void janet_mark_funcenv(JanetFuncEnv *env);
@ -97,8 +96,10 @@ static void janet_mark_abstract(void *adata) {
/* Mark a bunch of items in memory */ /* Mark a bunch of items in memory */
static void janet_mark_many(const Janet *values, int32_t n) { static void janet_mark_many(const Janet *values, int32_t n) {
const Janet *end = values + n; const Janet *end = values + n;
while (values < end) while (values < end) {
janet_mark(*values++); janet_mark(*values);
values += 1;
}
} }
/* Mark a bunch of key values items in memory */ /* Mark a bunch of key values items in memory */
@ -324,7 +325,7 @@ void *janet_gcalloc(enum JanetMemoryType type, size_t size) {
/* Run garbage collection */ /* Run garbage collection */
void janet_collect(void) { void janet_collect(void) {
size_t i; uint32_t i;
if (janet_vm_gc_suspend) return; if (janet_vm_gc_suspend) return;
depth = JANET_RECURSION_GUARD; depth = JANET_RECURSION_GUARD;
orig_rootcount = janet_vm_root_count; orig_rootcount = janet_vm_root_count;
@ -342,8 +343,17 @@ void janet_collect(void) {
* and all of its children. If gcroot is called on a value n times, unroot * and all of its children. If gcroot is called on a value n times, unroot
* must also be called n times to remove it as a gc root. */ * must also be called n times to remove it as a gc root. */
void janet_gcroot(Janet root) { void janet_gcroot(Janet root) {
janet_addtolist(root); uint32_t newcount = janet_vm_root_count + 1;
janet_vm_gc_marklist_rootcount++; if (newcount > janet_vm_root_capacity) {
uint32_t newcap = 2 * newcount;
janet_vm_roots = realloc(janet_vm_roots, sizeof(Janet) * newcap);
if (NULL == janet_vm_roots) {
JANET_OUT_OF_MEMORY;
}
janet_vm_root_capacity = newcap;
}
janet_vm_roots[janet_vm_root_count] = root;
janet_vm_root_count = newcount;
} }
/* Identity equality for GC purposes */ /* Identity equality for GC purposes */
@ -367,12 +377,12 @@ static int janet_gc_idequals(Janet lhs, Janet rhs) {
/* Remove a root value from the GC. This allows the gc to potentially reclaim /* Remove a root value from the GC. This allows the gc to potentially reclaim
* a value and all its children. */ * a value and all its children. */
int janet_gcunroot(Janet root) { int janet_gcunroot(Janet root) {
Janet *vtop = janet_vm_gc_marklist + janet_vm_gc_marklist_rootcount; Janet *vtop = janet_vm_roots + janet_vm_root_count;
Janet *v = janet_vm_gc_marklist; Janet *v = janet_vm_roots;
/* Search from top to bottom as access is most likely LIFO */ /* Search from top to bottom as access is most likely LIFO */
for (v = janet_vm_gc_marklist; v < vtop; v++) { for (v = janet_vm_roots; v < vtop; v++) {
if (janet_gc_idequals(root, *v)) { if (janet_gc_idequals(root, *v)) {
*v = janet_vm_gc_marklist[--janet_vm_gc_marklist_rootcount]; *v = janet_vm_roots[--janet_vm_root_count];
return 1; return 1;
} }
} }
@ -381,13 +391,13 @@ int janet_gcunroot(Janet root) {
/* Remove a root value from the GC. This sets the effective reference count to 0. */ /* Remove a root value from the GC. This sets the effective reference count to 0. */
int janet_gcunrootall(Janet root) { int janet_gcunrootall(Janet root) {
Janet *vtop = janet_vm_gc_marklist + janet_vm_gc_marklist_rootcount; Janet *vtop = janet_vm_roots + janet_vm_root_count;
Janet *v = janet_vm_gc_marklist; Janet *v = janet_vm_roots;
int ret = 0; int ret = 0;
/* Search from top to bottom as access is most likely LIFO */ /* Search from top to bottom as access is most likely LIFO */
for (v = janet_vm_gc_marklist; v < vtop; v++) { for (v = janet_vm_roots; v < vtop; v++) {
if (janet_gc_idequals(root, *v)) { if (janet_gc_idequals(root, *v)) {
*v = janet_vm_gc_marklist[--janet_vm_gc_marklist_rootcount]; *v = janet_vm_roots[--janet_vm_root_count];
vtop--; vtop--;
ret = 1; ret = 1;
} }

View File

@ -55,9 +55,9 @@ extern JANET_THREAD_LOCAL uint32_t janet_vm_gc_interval;
extern JANET_THREAD_LOCAL uint32_t janet_vm_next_collection; extern JANET_THREAD_LOCAL uint32_t janet_vm_next_collection;
extern JANET_THREAD_LOCAL int janet_vm_gc_suspend; extern JANET_THREAD_LOCAL int janet_vm_gc_suspend;
extern JANET_THREAD_LOCAL Janet *janet_vm_gc_marklist; /* GC roots */
extern JANET_THREAD_LOCAL size_t janet_vm_gc_marklist_count; extern JANET_THREAD_LOCAL Janet *janet_vm_roots;
extern JANET_THREAD_LOCAL size_t janet_vm_gc_marklist_capacity; extern JANET_THREAD_LOCAL uint32_t janet_vm_root_count;
extern JANET_THREAD_LOCAL size_t janet_vm_gc_marklist_rootcount; extern JANET_THREAD_LOCAL uint32_t janet_vm_root_capacity;
#endif /* JANET_STATE_H_defined */ #endif /* JANET_STATE_H_defined */

View File

@ -1335,11 +1335,10 @@ int janet_init(void) {
* there are no memory bugs during development */ * there are no memory bugs during development */
janet_vm_gc_interval = 0x10000; janet_vm_gc_interval = 0x10000;
janet_symcache_init(); janet_symcache_init();
/* Initialize gc list */ /* Initialize gc roots */
janet_vm_gc_marklist = NULL; janet_vm_roots = NULL;
janet_vm_gc_marklist_count = 0; janet_vm_root_count = 0;
janet_vm_gc_marklist_capacity = 0; janet_vm_root_capacity = 0;
janet_vm_gc_marklist_rootcount = 0;
/* Initialize registry */ /* Initialize registry */
janet_vm_registry = janet_table(0); janet_vm_registry = janet_table(0);
janet_gcroot(janet_wrap_table(janet_vm_registry)); janet_gcroot(janet_wrap_table(janet_vm_registry));
@ -1350,7 +1349,9 @@ int janet_init(void) {
void janet_deinit(void) { void janet_deinit(void) {
janet_clear_memory(); janet_clear_memory();
janet_symcache_deinit(); janet_symcache_deinit();
free(janet_vm_gc_marklist); free(janet_vm_roots);
janet_vm_gc_marklist = NULL; janet_vm_roots = NULL;
janet_vm_root_count = 0;
janet_vm_root_capacity = 0;
janet_vm_registry = NULL; janet_vm_registry = NULL;
} }