summaryrefslogtreecommitdiffstats
path: root/gc.c
diff options
context:
space:
mode:
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/gc.c b/gc.c
index 7df908c6..a644be3a 100644
--- a/gc.c
+++ b/gc.c
@@ -44,6 +44,8 @@
#define PROT_STACK_SIZE 1024
#define HEAP_SIZE 16384
+#define BACKPTR_VEC_SIZE 4096
+#define FULL_GC_INTERVAL 10
typedef struct heap {
struct heap *next;
@@ -72,6 +74,13 @@ static val heap_min_bound, heap_max_bound;
int gc_enabled = 1;
+#if CONFIG_GEN_GC
+static val backptr[BACKPTR_VEC_SIZE];
+static int backptr_idx;
+static int partial_gc_count;
+static int full;
+#endif
+
#if EXTRA_DEBUGGING
static val break_obj;
#endif
@@ -165,6 +174,9 @@ val make_obj(void)
if (opt_vg_debug)
VALGRIND_MAKE_MEM_UNDEFINED(ret, sizeof *ret);
#endif
+#if CONFIG_GEN_GC
+ ret->t.gen = 0;
+#endif
return ret;
}
@@ -472,6 +484,16 @@ void gc(void)
{
val gc_stack_top = nil;
+#if CONFIG_GEN_GC
+ if (backptr_idx && ++partial_gc_count == FULL_GC_INTERVAL) {
+ full = 1;
+ partial_gc_count = 0;
+ backptr_idx = 0;
+ } else {
+ full = 0;
+ }
+#endif
+
if (gc_enabled) {
mach_context_t mc;
save_context(mc);
@@ -513,6 +535,34 @@ int gc_is_reachable(val obj)
return (t & REACHABLE) != 0;
}
+#if CONFIG_GEN_GC
+
+val gc_set(val *ptr, val val)
+{
+ if (!is_ptr(val))
+ goto out;
+ if (val->t.gen != 0)
+ goto out;
+
+ backptr[backptr_idx++] = val;
+out:
+ *ptr = val;
+
+ if (backptr_idx == BACKPTR_VEC_SIZE)
+ gc();
+
+ return val;
+}
+
+void gc_mutated(val obj)
+{
+ backptr[backptr_idx++] = obj;
+ if (backptr_idx == BACKPTR_VEC_SIZE)
+ gc();
+}
+
+#endif
+
/*
* Useful functions for gdb'ing.
*/