diff options
-rw-r--r-- | ChangeLog | 20 | ||||
-rw-r--r-- | gc.c | 44 |
2 files changed, 45 insertions, 19 deletions
@@ -1,9 +1,29 @@ 2014-03-29 Kaz Kylheku <kaz@kylheku.com> + * gc.c (make_obj): If we have room in the freshobj array, + but are out of objects, then call more. Without this, + we don't take proper advantage of this nursing area. + (gc): Set the full_gc flag after doing gc, in preparation + for next time. If we know full GC is coming, we can + adjust some behaviors. Increase the threshold for calling the more() + function to be the same as in the non-generational case: + less than 3/4 of the size of a heap scavenged. + (gc_set): Now does nothing if it is known that + a full gc is coming. Also, in the checkobj array overflow + case when we invoke gc, there is no point in adding obj + to the array, since it must have been promoted to the mature + generation. + (gc_mutated): Don't bother storing the object in the + array if a full GC is coming. + +2014-03-29 Kaz Kylheku <kaz@kylheku.com> + * lib.c (string_time): If possible, change the timezone in the struct tm from "GMT" to "UTC", so that the time_string_utc function will use UTC for the %Z format. + Generational GC tweaks. + 2014-03-27 Kaz Kylheku <kaz@kylheku.com> Fix a bug arising from putting generation 1 objects into the @@ -187,6 +187,13 @@ val make_obj(void) return ret; } +#if CONFIG_GEN_GC + if (freshobj_idx < FRESHOBJ_VEC_SIZE) { + more(); + continue; + } +#endif + switch (tries) { case 0: gc(); break; case 1: more(); break; @@ -541,17 +548,12 @@ void gc(void) val gc_stack_top = nil; #if CONFIG_GEN_GC int exhausted = (free_list == 0); + int full_gc_next_time = 0; + static int gc_counter; #endif if (gc_enabled) { int swept; -#if CONFIG_GEN_GC - static int gc_counter; - if (++gc_counter >= FULL_GC_INTERVAL) { - full_gc = 1; - gc_counter = 0; - } -#endif mach_context_t mc; save_context(mc); @@ -564,9 +566,11 @@ void gc(void) printf("sweep: freed %d full_gc == %d exhausted == %d\n", (int) swept, full_gc, exhausted); #endif - if (full_gc && swept < 3 * HEAP_SIZE / 4) - more(); - else if (!full_gc && swept < HEAP_SIZE / 4 && exhausted) + if (++gc_counter >= FULL_GC_INTERVAL - 1) { + full_gc_next_time = 1; + gc_counter = 0; + } + if (exhausted && full_gc && swept < 3 * HEAP_SIZE / 4) more(); #else if (swept < 3 * HEAP_SIZE / 4) @@ -577,7 +581,7 @@ void gc(void) checkobj_idx = 0; mutobj_idx = 0; freshobj_idx = 0; - full_gc = 0; + full_gc = full_gc_next_time; #endif gc_enabled = 1; } @@ -621,12 +625,14 @@ int gc_is_reachable(val obj) val gc_set(val *ptr, val obj) { - if (checkobj_idx >= CHECKOBJ_VEC_SIZE) { - gc(); - /* obj can't be in gen 0 because there are no baby objects after gc */ - } else if (in_malloc_range((mem_t *) ptr) && is_ptr(obj) && obj->t.gen == 0) { - obj->t.gen = -1; - checkobj[checkobj_idx++] = obj; + if (!full_gc) { + if (checkobj_idx >= CHECKOBJ_VEC_SIZE) { + gc(); + /* obj can't be in gen 0 because there are no baby objects after gc */ + } else if (in_malloc_range((mem_t *) ptr) && is_ptr(obj) && obj->t.gen == 0) { + obj->t.gen = -1; + checkobj[checkobj_idx++] = obj; + } } *ptr = obj; return obj; @@ -635,8 +641,8 @@ val gc_set(val *ptr, val obj) val gc_mutated(val obj) { /* We care only about mature generation objects that have not - already been noted. */ - if (obj->t.gen <= 0) + already been noted. And if a full gc is coming, don't bother. */ + if (full_gc || obj->t.gen <= 0) return obj; obj->t.gen = -1; /* Store in mutobj array *before* triggering gc, otherwise |