summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--gc.c13
2 files changed, 22 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index eb578f74..f23f8107 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2014-09-06 Kaz Kylheku <kaz@kylheku.com>
+
+ Make the garbage collector aware of malloced bytes, to
+ prevent skyrocketing memory use when the program manipulates
+ heap objects that have large amounts of malloc memory
+ attached, like very large bignums.
+
+ * gc.c (MALLOC_DELTA_THRESH): New preprocessor symbol.
+ (prev_malloc_bytes): New static variable.
+ (make_obj): when the value of malloc_bytes jumps by MALLOC_DELTA_THRESH
+ or more since the last gc, trigger gc.
+
2014-09-03 Kaz Kylheku <kaz@kylheku.com>
* lib.c (symbol_setname): New static function.
diff --git a/gc.c b/gc.c
index 9d5b61b9..3143530a 100644
--- a/gc.c
+++ b/gc.c
@@ -49,6 +49,7 @@
#define MUTOBJ_VEC_SIZE (HEAP_SIZE / 4)
#define FULL_GC_INTERVAL 40
#define FRESHOBJ_VEC_SIZE (8 * HEAP_SIZE)
+#define MALLOC_DELTA_THRESH (64L * 1024 * 1024)
typedef struct heap {
struct heap *next;
@@ -76,6 +77,7 @@ static heap_t *heap_list;
static val heap_min_bound, heap_max_bound;
alloc_bytes_t gc_bytes;
+static alloc_bytes_t prev_malloc_bytes;
int gc_enabled = 1;
@@ -153,17 +155,22 @@ static void more(void)
val make_obj(void)
{
int tries;
-
+ alloc_bytes_t malloc_delta = malloc_bytes - prev_malloc_bytes;
assert (!async_sig_enabled);
#if CONFIG_GEN_GC
- if (opt_gc_debug || freshobj_idx >= FRESHOBJ_VEC_SIZE) {
+ if (opt_gc_debug || freshobj_idx >= FRESHOBJ_VEC_SIZE ||
+ malloc_delta >= MALLOC_DELTA_THRESH)
+ {
gc();
assert (freshobj_idx < FRESHOBJ_VEC_SIZE);
+ prev_malloc_bytes = malloc_bytes;
}
#else
- if (opt_gc_debug)
+ if (opt_gc_debug || malloc_delta >= MALLOC_DELTA_THRESH) {
gc();
+ prev_malloc_bytes = malloc_bytes;
+ }
#endif
for (tries = 0; tries < 3; tries++) {