mirror of
https://github.com/janet-lang/janet
synced 2025-06-22 00:14:12 +00:00
Allow use of stack in gc.
This commit is contained in:
parent
f0553e9da7
commit
f5372dd188
@ -50,10 +50,12 @@ static void janet_mark_string(const uint8_t *str);
|
|||||||
static void janet_mark_fiber(JanetFiber *fiber);
|
static void janet_mark_fiber(JanetFiber *fiber);
|
||||||
static void janet_mark_abstract(void *adata);
|
static void janet_mark_abstract(void *adata);
|
||||||
|
|
||||||
/* Mark a value (Pushes it to the black list).*/
|
static JANET_THREAD_LOCAL int recursion_depth;
|
||||||
void janet_mark(Janet x) {
|
|
||||||
|
/* Add a janet to the list for later processing */
|
||||||
|
static void janet_addtolist(Janet x) {
|
||||||
if (janet_vm_gc_marklist_count >= janet_vm_gc_marklist_capacity) {
|
if (janet_vm_gc_marklist_count >= janet_vm_gc_marklist_capacity) {
|
||||||
janet_vm_gc_marklist_capacity = (3 * janet_vm_gc_marklist_count) / 2 + 1;
|
janet_vm_gc_marklist_capacity = (2 * janet_vm_gc_marklist_count) + 1;
|
||||||
janet_vm_gc_marklist = realloc(janet_vm_gc_marklist,
|
janet_vm_gc_marklist = realloc(janet_vm_gc_marklist,
|
||||||
janet_vm_gc_marklist_capacity * sizeof(Janet));
|
janet_vm_gc_marklist_capacity * sizeof(Janet));
|
||||||
if (NULL == janet_vm_gc_marklist) {
|
if (NULL == janet_vm_gc_marklist) {
|
||||||
@ -63,6 +65,30 @@ void janet_mark(Janet x) {
|
|||||||
janet_vm_gc_marklist[janet_vm_gc_marklist_count++] = x;
|
janet_vm_gc_marklist[janet_vm_gc_marklist_count++] = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mark a value Recurses on x, or pushes it to the black list
|
||||||
|
* if recursed too deeply (ran out of C stack).*/
|
||||||
|
void janet_mark(Janet x) {
|
||||||
|
if (recursion_depth) {
|
||||||
|
recursion_depth--;
|
||||||
|
switch (janet_type(x)) {
|
||||||
|
default: break;
|
||||||
|
case JANET_STRING:
|
||||||
|
case JANET_SYMBOL: janet_mark_string(janet_unwrap_string(x)); break;
|
||||||
|
case JANET_FUNCTION: janet_mark_function(janet_unwrap_function(x)); break;
|
||||||
|
case JANET_ARRAY: janet_mark_array(janet_unwrap_array(x)); break;
|
||||||
|
case JANET_TABLE: janet_mark_table(janet_unwrap_table(x)); break;
|
||||||
|
case JANET_STRUCT: janet_mark_struct(janet_unwrap_struct(x)); break;
|
||||||
|
case JANET_TUPLE: janet_mark_tuple(janet_unwrap_tuple(x)); break;
|
||||||
|
case JANET_BUFFER: janet_mark_buffer(janet_unwrap_buffer(x)); break;
|
||||||
|
case JANET_FIBER: janet_mark_fiber(janet_unwrap_fiber(x)); break;
|
||||||
|
case JANET_ABSTRACT: janet_mark_abstract(janet_unwrap_abstract(x)); break;
|
||||||
|
}
|
||||||
|
recursion_depth++;
|
||||||
|
} else {
|
||||||
|
janet_addtolist(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void janet_mark_string(const uint8_t *str) {
|
static void janet_mark_string(const uint8_t *str) {
|
||||||
janet_gc_mark(janet_string_raw(str));
|
janet_gc_mark(janet_string_raw(str));
|
||||||
}
|
}
|
||||||
@ -312,25 +338,14 @@ void *janet_gcalloc(enum JanetMemoryType type, size_t size) {
|
|||||||
void janet_collect(void) {
|
void janet_collect(void) {
|
||||||
size_t i;
|
size_t i;
|
||||||
if (janet_vm_gc_suspend) return;
|
if (janet_vm_gc_suspend) return;
|
||||||
|
recursion_depth = JANET_RECURSION_GUARD;
|
||||||
/* Mark the roots */
|
/* Mark the roots */
|
||||||
for (i = 0; i < janet_vm_gc_marklist_rootcount; i++)
|
for (i = 0; i < janet_vm_gc_marklist_rootcount; i++)
|
||||||
janet_mark(janet_vm_gc_marklist[i]);
|
janet_mark(janet_vm_gc_marklist[i]);
|
||||||
/* While list not empty */
|
/* While list not empty */
|
||||||
while (janet_vm_gc_marklist_count > janet_vm_gc_marklist_rootcount) {
|
while (janet_vm_gc_marklist_count > janet_vm_gc_marklist_rootcount) {
|
||||||
Janet x = janet_vm_gc_marklist[--janet_vm_gc_marklist_count];
|
Janet x = janet_vm_gc_marklist[--janet_vm_gc_marklist_count];
|
||||||
switch (janet_type(x)) {
|
janet_mark(x);
|
||||||
default: break;
|
|
||||||
case JANET_STRING:
|
|
||||||
case JANET_SYMBOL: janet_mark_string(janet_unwrap_string(x)); break;
|
|
||||||
case JANET_FUNCTION: janet_mark_function(janet_unwrap_function(x)); break;
|
|
||||||
case JANET_ARRAY: janet_mark_array(janet_unwrap_array(x)); break;
|
|
||||||
case JANET_TABLE: janet_mark_table(janet_unwrap_table(x)); break;
|
|
||||||
case JANET_STRUCT: janet_mark_struct(janet_unwrap_struct(x)); break;
|
|
||||||
case JANET_TUPLE: janet_mark_tuple(janet_unwrap_tuple(x)); break;
|
|
||||||
case JANET_BUFFER: janet_mark_buffer(janet_unwrap_buffer(x)); break;
|
|
||||||
case JANET_FIBER: janet_mark_fiber(janet_unwrap_fiber(x)); break;
|
|
||||||
case JANET_ABSTRACT: janet_mark_abstract(janet_unwrap_abstract(x)); break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
janet_sweep();
|
janet_sweep();
|
||||||
janet_vm_next_collection = 0;
|
janet_vm_next_collection = 0;
|
||||||
@ -340,7 +355,7 @@ 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_mark(root);
|
janet_addtolist(root);
|
||||||
janet_vm_gc_marklist_rootcount++;
|
janet_vm_gc_marklist_rootcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1333,7 +1333,7 @@ int janet_init(void) {
|
|||||||
* a collection pretty much every cycle, which is
|
* a collection pretty much every cycle, which is
|
||||||
* incredibly horrible for performance, but can help ensure
|
* incredibly horrible for performance, but can help ensure
|
||||||
* there are no memory bugs during development */
|
* there are no memory bugs during development */
|
||||||
janet_vm_gc_interval = 0x4000000;
|
janet_vm_gc_interval = 0x10000;
|
||||||
janet_symcache_init();
|
janet_symcache_init();
|
||||||
/* Initialize gc list */
|
/* Initialize gc list */
|
||||||
janet_vm_gc_marklist = NULL;
|
janet_vm_gc_marklist = NULL;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user