diff options
-rw-r--r-- | ChangeLog | 22 | ||||
-rw-r--r-- | gc.c | 26 | ||||
-rw-r--r-- | gc.h | 1 | ||||
-rw-r--r-- | genvim.txr | 2 | ||||
-rw-r--r-- | lib.c | 1 | ||||
-rw-r--r-- | txr.1 | 58 | ||||
-rw-r--r-- | txr.c | 9 | ||||
-rw-r--r-- | txr.h | 1 |
8 files changed, 116 insertions, 4 deletions
@@ -1,3 +1,25 @@ +2014-09-08 Kaz Kylheku <kaz@kylheku.com> + + * gc.c (MALLOC_DELTA_THRESH): Macro remaned to DFL_MALLOC_DELTA_THRESH. + (opt_gc_delta): New global variable. + (make_obj): Use opt_gc_delta rather than MALLOC_DELTA_THRESH. + (gc_set_delta, gc_wrap): New static functions. + (gc_late_init): New function. + + * gc.h (gc_late_init): Declared. + + * genvim.txr: scan gc.c also. + + * lib.c (init): call gc_late_init. + + * txr.1: Document new --gc-delta option and the functions + gc and gc-set-delta. + + * txr.c (help): Help text for --gc-delta. + (txr_main): Parse --gc-delta option. + + * txr.h (opt_gc_delta): Declared. + 2014-09-06 Kaz Kylheku <kaz@kylheku.com> Make the garbage collector aware of malloced bytes, to @@ -40,6 +40,7 @@ #include "stream.h" #include "hash.h" #include "txr.h" +#include "eval.h" #include "gc.h" #include "signal.h" @@ -49,7 +50,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) +#define DFL_MALLOC_DELTA_THRESH (64L * 1024 * 1024) typedef struct heap { struct heap *next; @@ -78,6 +79,7 @@ static val heap_min_bound, heap_max_bound; alloc_bytes_t gc_bytes; static alloc_bytes_t prev_malloc_bytes; +alloc_bytes_t opt_gc_delta = DFL_MALLOC_DELTA_THRESH; int gc_enabled = 1; @@ -160,14 +162,14 @@ val make_obj(void) #if CONFIG_GEN_GC if (opt_gc_debug || freshobj_idx >= FRESHOBJ_VEC_SIZE || - malloc_delta >= MALLOC_DELTA_THRESH) + malloc_delta >= opt_gc_delta) { gc(); assert (freshobj_idx < FRESHOBJ_VEC_SIZE); prev_malloc_bytes = malloc_bytes; } #else - if (opt_gc_debug || malloc_delta >= MALLOC_DELTA_THRESH) { + if (opt_gc_debug || malloc_delta >= opt_gc_delta) { gc(); prev_malloc_bytes = malloc_bytes; } @@ -670,6 +672,24 @@ val gc_push(val obj, loc plist) #endif +static val gc_set_delta(val delta) +{ + opt_gc_delta = c_num(delta); + return nil; +} + +static val gc_wrap(void) +{ + gc(); + return nil; +} + +void gc_late_init(void) +{ + reg_fun(intern(lit("gc"), system_package), func_n0(gc_wrap)); + reg_fun(intern(lit("gc-set-delta"), system_package), func_n1(gc_set_delta)); +} + /* * Useful functions for gdb'ing. */ @@ -25,6 +25,7 @@ */ void gc_init(val *stack_bottom); +void gc_late_init(void); val prot1(val *loc); void rel1(val *loc); void protect(val *, ...); @@ -7,7 +7,7 @@ static void dir_tables_init(void) @(until) } @(end) -@(next @(open-files '("eval.c" "rand.c" "signal.c" "stream.c" +@(next @(open-files '("eval.c" "rand.c" "signal.c" "stream.c" "gc.c" "syslog.c" "filter.c" "txr.c" "arith.c"))) @(collect) @ (block) @@ -6641,6 +6641,7 @@ void init(const wchar_t *pn, mem_t *(*oom)(mem_t *, size_t), filter_init(); hash_init(); regex_init(); + gc_late_init(); gc_state(gc_save); } @@ -206,6 +206,13 @@ supports that behavior, or even that exact version. For more information, see the COMPATIBILITY section. +.IP "--gc-delta=number" + +The argument to this option must be a decimal integer. It represents +a megabyte value, the "GC delta": one megabyte is 1048576 bytes. The "GC +delta" controls an aspect of the garbage collector behavior. +See the gc-set-delta function for a description. + .IP --help Prints usage summary on standard output, and terminates successfully. @@ -15839,6 +15846,57 @@ pprof prints these statistics are printed in a concise report on the The pprof macro relies on the prof operator. +.SH GARBAGE COLLECTION + +.SS Function sys:gc + +.TP +Syntax: + + (sys:gc) + +.TP +Description: + +The gc function triggers garbage collection. Garbage collection means +that unreachable objects are identified and reclaimed, so that their +storage can be re-used. + +.SS Function sys:gc-set-delta + +.TP +Syntax: + + (sys:gc-set-delta <bytes>) + +.TP +Description: + +The gc-set-delta function sets the GC delta parameter. + +Note: This function may disappear in a future release of TXR or suffer +a backward-incompatible change in its syntax or behavior. + +When the amount of new dynamic memory allocated since the last garbage +collection equals or exceeds the GC delta, a garbage collection pass is +triggered. From that point, a new delta begins to be accumulated. + +Dynamic memory is used for allocating heaps of small garbage-collected objects +such as cons cells, as well as the satellite data attached to some objects: +like the storage arrays of vectors, strings or bignum integers. Most garbage +collector behaviors are based on counting objects in the heaps. + +Sometimes a program works with a small number of objects which are very large, +frequently allocating new, large objects and turning old ones into garbage. +For instance a single large integer could be many megabytes long. In such a +situation, a small number of heap objects therefore control a large amount of +memory. This requires garbage collection to be triggered much more often than +when working with small objects, such as conses, to prevent runaway allocation +of memory. It is for this reason that the garbage collector uses the GC delta. + +There is a default GC delta of 64 megabytes. This may be overridden in +special builds of TXR for small systems. + .SH MODULARIZATION .SS Special variable *self-path* @@ -129,6 +129,8 @@ static void help(void) " section at the bottom of the license.\n" "--lisp-bindings Synonym for -l\n" "--debugger Synonym for -d\n" +"--gc-delta=N Invoke garbage collection when malloc activity\n" +" increments by N megabytes since last collection.\n" "\n" "Options that take no argument can be combined. The -q and -v options\n" "are mutually exclusive; the right-most one dominates.\n" @@ -356,6 +358,13 @@ int txr_main(int argc, char **argv) continue; } + if (match_str(arg, lit("--gc-delta="), zero)) { + val megs = mul(int_str(sub(arg, num_fast(11), t), num_fast(10)), + num_fast(1048576)); + opt_gc_delta = c_num(megs); + continue; + } + if (equal(arg, lit("--version"))) { format(std_output, lit("~a: version ~a\n"), prog_string, auto_str(version), nao); @@ -34,5 +34,6 @@ extern int opt_vg_debug; #endif extern int opt_derivative_regex; extern int opt_compat; +extern alloc_bytes_t opt_gc_delta; extern const wchli_t *version; extern const wchar_t *progname; |