summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-03-29 10:54:22 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-03-29 22:55:16 -0700
commitc20c994098c12f499fd24a89305ff37c7a2bcf76 (patch)
treea302673b8794c768261b08ded7e14a8bda3c2310
parentdfee517e54d27412e28481637ba7d763ec34face (diff)
downloadtxr-c20c994098c12f499fd24a89305ff37c7a2bcf76.tar.gz
txr-c20c994098c12f499fd24a89305ff37c7a2bcf76.tar.bz2
txr-c20c994098c12f499fd24a89305ff37c7a2bcf76.zip
Generational GC tweaks.
* 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.
-rw-r--r--ChangeLog20
-rw-r--r--gc.c44
2 files changed, 45 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index 3bbbceae..1bf6cf19 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/gc.c b/gc.c
index d58f2a59..2c11d678 100644
--- a/gc.c
+++ b/gc.c
@@ -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