| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Makefile, args.c, args.h, arith.c, arith.h, cadr.c, cadr.h, combi.c,
combi.h, configure, debug.c, debug.h, eval.c, eval.h, filter.c,
filter.h, ftw.c, ftw.h, gc.c, gc.h, glob.c, glob.h, hash.c, hash.h,
jmp.S, lib.c, lib.h, lisplib.c, lisplib.h, match.c, match.h, parser.c,
parser.h, parser.l, parser.y, rand.c, rand.h, regex.c, regex.h,
share/txr/stdlib/awk.tl, share/txr/stdlib/build.tl,
share/txr/stdlib/cadr.tl, share/txr/stdlib/conv.tl,
share/txr/stdlib/except.tl, share/txr/stdlib/hash.tl,
share/txr/stdlib/ifa.tl, share/txr/stdlib/path-test.tl,
share/txr/stdlib/place.tl, share/txr/stdlib/socket.tl,
share/txr/stdlib/struct.tl, share/txr/stdlib/termios.tl,
share/txr/stdlib/txr-case.tl, share/txr/stdlib/type.tl,
share/txr/stdlib/with-resources.tl, share/txr/stdlib/with-stream.tl,
share/txr/stdlib/yield.tl, signal.c, signal.h, socket.c, socket.h,
stream.c, stream.h, struct.c, struct.h, sysif.c, sysif.h, syslog.c,
syslog.h, termios.c, termios.h, txr.1, txr.c, txr.h, unwind.c,
unwind.h, utf8.c, utf8.h: Revert to verbatim 2-Clause BSD.
|
|
|
|
|
|
|
|
| |
* configure: Generate #define CONFIG_EXTRA_DEBUGGING 1 in
config.h header, rather than EXTRA_DEBUGGING.
* gc.c, gc.h, hash.c: Change references to EXTRA_DEBUGGING
preprocessor symbol to CONFIG_EXTRA_DEBUGGING.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* gc.c (more): Under EXTRA_DEBUGGING, call breakpt()
here also, when it is detected that break_obj is
added to the free list for the firts time.
Print a message and backtrace using
VALGRIND_PRINTF_BACKTRACE.
(make_obj): Likewise, for an object that is pulled out
of the free list and returned.
(mark_obj, sweep_one): Print backtrace with Valgrind for
break_obj, in addition to calling breakpt().
|
|
|
|
|
| |
* gc.c (make_obj): Assert that the object we are pulling
from the free list is marked FREE.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* gc.c (more): Only set the free_tail if the
new memory is being added to an empty free_list.
Otherwise free_tail is valid.
(make_obj): If we empty the free_list, then
reset the free_tail pointer, so it doesn't
continue pointing into the object we are returning.
(sweep): Remove defensive code which tries to reset
the free_tail in the empty free_list case,
but assumes that free_tail is correct in the non-empty
case.
|
|
|
|
|
|
|
|
|
|
| |
* gc.c (sweep_one): Don't check for gen == -1;
no reachable object can have that at this stage,
since mark flips -1 objects to gen 0.
(sweep): Do not clear freshobj_idx here;
completely revert the mark_markfresh code.
(gc): Clear freshobj_idx here., as before
the mark_makefresh hack.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Although we are garbage-collected, being able to clean up on
shutdown is nevertheless useful for uncovering leaks. Leaks
can occur, for instance, due to neglect to free out-of-heap
satellite data from objects that are reclaimed by gc.
This feature is long overdue.
* arith.c, arith.h (arith_free_all): New function.
* gc.c, gc.h (gc_free_all): New function.
* lib.c (init): Remove program name parameter and
redundant initialization of progname globl variable.
* lib.h (progname): Superfluous declaration removed.
This is already declared in txr.h.
(init): Declaration updated.
* regex.c (char_set_destroy): Do not check the static
allocation flag here; just destroy the object.
Do check for a null pointer, though.
(char_set_cobj_destroy): This cobj destructor now
checks the static flag of the char set object and
avoids freeing it. Thus our char set singletons are
left alone by gc, but our global freeing function
takes care of them.
(wide_cs): New static variable moved out of
wide_display_char_p to static scope.
(regex_free_all): New function.
* regex.h (regex_free_all): Declared.
* txr.c (progname): const qualifier and initializer removed.
(main): Ensure progname is always dynamically allocated, even
in the argv[0] == 0 case. Do not pass progname to init;
it doesn't take that argument any more.
(free_all): New static function.
(txr_main): Implement --free-all option.
* txr.h (progname): Declaration updated.
|
|
|
|
|
| |
* gc.c (gc_set): Should say "promote obj to gen 1",
not "to gen 0".
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (recycled_conses): New static variable.
(rcyc_pop, rcyc_cons, rcyc_list, rcyc_empty): New functions.
(cons): Take a recycled cons, if available.
* lib.h (rcyc_pop, rcyc_cons, rcyc_list,
rcyc_empty): Declared.
* gc.c (gc): Call rcyc_empty to make recycle_list
unreachable.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* gc.c (gc_report_copies): C style casts found in this
function.
* linenoise.c (strip_qual, convert, coerce): Copy and paste
the macros here.
(record_undo, compare_completions, lino_add_completion,
history_search, ab_append, sync_data_to_buf,
refresh_singleline, screen_rows, refresh_multiline,
find_nearest_paren, paren_jump, yank_sel,
edit_move_matching_paren, edit, lino_make, lino_copy,
lino_hist_add, lino_hist_set_max_len): C style casts
replaced.
* mpi/mpi-types.h (MP_DIGIT_BIT, MP_DIGIT_MAX, MP_WORD_BIT,
MP_WORD_MAX, RADIX): C style casts replaced.
* mpi/mpi.c (convert, coerce): Copy and paste the macros here.
(mp_init_size, mp_init_copy, mp_copy, mp_set_int, mp_div_d,
mp_bit, mp_to_double, mp_to_signed_bin, mp_to_unsigned_bin,
mp_to_unsigned_buf, mp_toradix_case, mp_grow, s_mp_set_bit,
s_mp_mod_2d, s_mp_mul_2d, s_mp_div_2d, s_mp_mul_d, s_mp_mul,
s_mp_sqr, s_mp_div, s_mp_2expt, s_mp_todigit): C style
casts replaced.
* mpi/mplogic (convert): Macro copy and pasted here.
(mpl_num_set, mpl_num_clear): C style casts replaced.
* parser.c (provide_completions): Likewise.
* signal.c (small_sigfillset): Likewise.
* stream.c (stdio_truncate, test_set_indent_mode,
set_indent_mode): Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* gc.c (finalize): Must free the dynamic structure attached
to the LSTR type now.
(mark_obj): Must mark interior of LSTR type's props structure.
* lib.c (lazy_sub_str, copy_lazy_str): Copy props structure.
(lazy_str): Allocate and initialize props structure.
(lazy_str_force, lazy_str_put, lazy_str_force_upto,
lazy_str_get_trailing_list, out_lazy_str): Follow
representation change.
* lib.h (struct lazy_string_props): New struct type.
(strut lazy_string): Member opts replaced with props
pointer to struct lazy_string_props.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* LICENSE, METALICENSE, Makefile, args.c, args.h, arith.c,
arith.h, cadr.c, cadr.h, combi.c, combi.h, configure,
debug.c, debug.h, eval.c, eval.h, filter.c, filter.h, gc.c,
gc.h, glob.c, glob.h, hash.c, hash.h, jmp.S, lib.c, lib.h,
lisplib.c, lisplib.h, match.c, match.h, parser.c, parser.h,
parser.l, parser.y, rand.c, rand.h, regex.c, regex.h,
share/txr/stdlib/cadr.tl, share/txr/stdlib/except.tl,
share/txr/stdlib/hash.tl, share/txr/stdlib/ifa.tl,
share/txr/stdlib/path-test.tl, share/txr/stdlib/place.tl,
share/txr/stdlib/struct.tl, share/txr/stdlib/txr-case.tl,
share/txr/stdlib/type.tl, share/txr/stdlib/with-resources.tl,
share/txr/stdlib/with-stream.tl, share/txr/stdlib/yield.tl,
signal.c, signal.h, stream.c, stream.h, struct.c, struct.h,
sysif.c, sysif.h, syslog.c, syslog.h, txr.1, txr.c, txr.h,
unwind.c, unwind.h, utf8.c, utf8.h: Add 2016 copyright.
* linenoise/LICENSE, linenoise/linenoise.c,
linenoise/linenoise.h: Bump one principal author's copyright
from 2014 to 2015. The code is based on a snapshot of 2015
upstream work.
|
|
|
|
|
|
| |
* gc.c (gc_report_copies): New function
* gc.h (gc_report_copies): Declared.
|
|
|
|
|
|
| |
* gc.c (rel1): Removed.
* gc.h (rel1): Declaration removed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register intrinsic functions rcons,
rangep from and to.
(eval_init): Register rangep intrinsic.
* gc.c (mark_obj): Traverse RNG objects.
(finalize): Handle RNG in switch.
* hash.c (equal_hash, eql_hash): Hashing for for RNG objects.
* lib.c (range_s, rcons_s): New symbol variables.
(code2type): Handle RNG type.
(eql, equal): Equality for ranges.
(less_tab_init): Table extended to cover RNG.
(less): Semantics defined for ranges.
(rcons, rangep, from, to): New functions.
(obj_init): range_s and rcons_s variables initialized.
(obj_print_impl): Produce #R notation for ranges.
(generic_funcall, dwim_set): Recognize range objects for indexing
* lib.h (enum type): New enum member, RNG. MAXTYPE redefined
to RNG value.
(TYPE_SHIFT): Increased to 5 since there are now 16 type
codes.
(struct range): New struct type.
(union obj): New member rn, of type struct range.
(range_s, rcons_s, rcons, rangep, from, to): Declared.
(range_bind): New macro.
* parser.l (grammar): New rule for recognizing
the #R sequence as HASH_R token.
* parser.y (HASH_R): New terminal symbol.
(range): New nonterminal symbol.
(n_expr): Derives the new range symbol.
The n_expr DOTDOT n_expr rule produces rcons expression rather
than const.
* match.c (format_field): Recognize rcons syntax in fields
which is now what ranges translate to. Also recognize range
object.
* tests/013/maze.tl (neigh): Fix code which destructures
range as a cons. That can't be done any more.
* txr.1: Document ranges.
|
|
|
|
|
|
| |
* gc.c (gc_mark_mem): New function.
* gc.h (gc_mark_mem): Declared.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
TXR is moving to custom assembly-language routines.
This is mainly motivated by a very dubious thing done in the
GNU C Library setjmp and longjmp in the name of security.
Evidently, glibc's setjmp "mangles" certain pointer values
which are stored into the jmp_buf buffer. It's been that way
since 2005, evidently. This means that, firstly, all along,
the use of setjmp in gc.c to get registers into a buffer so
they can be scanned has not actually worked properly. More
importantly, this pointer mangling in setjmp and longjmp is
very hostile to a stack copying implementation of delimited
continuations. The reason is that continuations contain
jmp_buf buffers, which get relocated in the process of
capturing and reviving a continuation. Any pointers in a
jmp_buf which point into the captured stack segment have to be
fixed up to point into the relocated location. Mangled
pointers make this difficult, requiring hacks which are
specific to glibc and the machine architecture. We might as
well implement a clean, well-behaved setjmp and longjmp.
* Makefile (jmp.o): New object file.
(dbg/%.o, opt/%.o): New rules for .S prerequisites.
* args.c, arith.c, cadr.c, combi.c, cadr.c, combi.c, debug.c,
eval.c, filter.c, glob.c, hash.c, lib.c, match.c, parser.c,
rand.c, regex.c, signal.c, stream.c, struct.c, sysif.c,
syslog.c, txr.c, unwind.c, utf8.c: Removed <setjmp.h>
include.
* gc.c: Switch to struct jmp and jmp_save, instead
of jmp_buf and setjmp.
* jmp.S: New source file.
* signal.h (struct jmp): New struct type.
(jmp_save, jmp_restore): New function declarations
denoting assembly language routines in jmp.S.
(extended_jmp_buf): Uses struct jmp instead of
setjmp.
(extended_setjmp): Use jmp_save instead of setjmp.
(extended_longjmp): Use jmp_restore instead of
longjmp.
|
|
|
|
|
|
|
|
|
| |
* gc.c (gc_call_finalizers): New function.
(gc_late_init): Register call-finalizers intrinsic.
* gc.h (gc_call_finalizers): Declared.
* txr.1: documented call-finalizers.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A new optional argument on finalize allows it to
be expressed that multiple finalizers on the same
object are to be called in reverse order, which is
potentially for objects with inheritance.
* gc.c (gc_finalize): New optional argument, rev_order_p.
Insert at the head of the list if this argument is
specified and true.
(gc_late_init): Register finalize as three-argument
function with optional argument.
* gc.h (gc_finalize): Declaration updated.
* share/txr/stdlib/struct.tl (defstruct): Register :fini
functions in reverse, so that derived finalizers
are called before supertype finalizers.
* txr.1: Documented new finalize argument, and
behavior of :fini.
|
|
|
|
|
|
|
|
|
| |
* gc.c (gc): If the number of bytes malloced since the
last gc exceeds the gc delta, we must do do a full garbage
collection. The mature generation is almost certainly holding
on to a lot of that memory. A test case for this
is (lazy-str-force (lazy-str (get-lines (open-file "file")))).
The file doesn't even have to be very large.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* gc.c (prepare_finals): In the second pass, only mark
objects that were identified in the first pass as unreachable.
Reachable ones don't require a redundant call to mark_obj.
Also, objects identified as unreachable can be moved to
gen 0. This is something like what the mark_makefresh hack was
trying to do. It only does anything in a full GC pass, because
in an incremental pass, anything identified as unreachable is
necessarily gen 0. It can help prevent some objects that
are revived by finalization from sliding back to gen 1
and hanging around.
|
|
|
|
|
|
|
|
|
| |
This contraption doesn't actually do anything.
* gc.c (mark_makefresh): Static variable removed.
(mark_obj): Remove logic conditional no mark_makefresh.
(prepare_finals): Remove setting of mark_makefresh.
(call_finals): Remove clearing of mark_makefresh.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Another bug found in the finalization hooks. The reachability
test being applied is not correct for generational GC,
relying only on the REACHABLE flag. This bug means that we
call finalization hooks on mature objects, while they remain
reachable. It must use the gc_is_reachable logic, just like
weak hash table processing does, because under an incremental
garbage collection pass, all gen 1 objects are considered
reachable (though they don't have the REACHABLE flag set).
* gc.c (struct fin_reg): Remving obj_type member, replacing
with reachable flag.
(is_reachable): New static function based on gc_is_reachable,
minus the is_ptr test. (GC code which knows it is dealing with
a pointer doesn't need the test).
(prepare_finals): In the first pass, instead of memorizing the
prior object type, simply calculate the reachable flag,
correctly taking into account generational GC.
(call_finals): Rely on the new reachable flag rather than
the REACHABLE flag in the saved obj_type.
(gc_is_reachable): Becomes a public wrapper for is_reachable
which adds the pointer test.
(gc_finalize): Initialize the reachable member of fin_reg.
Remove initialization for obj_type.
|
|
|
|
|
|
|
| |
* gc.c (call_finals): Correct inverted test for reachability.
The function was processing entries that are still reachable
and calling their finalizers, and retaining unreachable
entries in the finalization list.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The issue is that we can't call remhash in the cobj destroy
handler, because we are in the middle of gc. The fix is to
register a proper finalization hook. This is the first use of
finalize from within TXR.
* gc.c (gc_finalize): static becomes extern.
* gc.h (gc_finalize): Declared.
* struct.c (struct_type_finalize_f): New static variable.
(struct_init): GC-protect new static variable, and initialize
it to point to new struct_type_finalize function.
(struct_type_finalize): New function: performs the remhash
calls previously done in struct_type_free.
(make_struct_type): Register a finalizer hook for every new
structure type, which will call struct_type_finalize.
(struct_type_free): Static function removed.
(struct_type_ops): Use generic cobj_destroy_free_op since
all that is left to do is to free the handle.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* args.c (args_cat_zap): New function.
* args.h: (args_cat_zap): Declared.
* eval.c (struct_lit_s): New symbol variable.
(eval_init): Initialize struct_lit_s.
* eval.h (struct_lit_s): Declared.
* gc.c (finalize): If a symbol has a struct slot
hash attached to it, we must free it when
the symbol is reclaimed.
* lib.c (make_sym): Initialize symbol's slot_cache pointer
to null.
(copy): Copy structure objects.
(init): Call struct_init to initialize struct module.
* lib.h (SLOT_CACHE_SIZE): New preprocessor symbol
(slot_cache_line_t, slot_cache_t): New typedefs.
(struct sym): New member, slot_cache.
* lisplib.c (struct_set_entries, struct_instantiate): New
static functions.
(liplib_init): Register new functions in dl_table.
parser.y (HASH_S): New terminal symbol.
(struct): New grammar rule.
(n_expr): Derive struct.
(yybadtoken): Map HASH_S to #S string.
parser.l (grammar): Recognize #S and return HASH_S token.
share/txr/stdlib/place.tl (slot): New defplace.
share/txr/stdlib/struct.tl: New file.
struct.c: New file.
struct.h: New file.
* Makefile (OBJS): Adding struct.o.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
GC now exports a function for marking something that might not
be an object, instead of a function for testing.
The previous way wasn't integrated with Valgrind properly,
and didn't observe the FREE flag.
* gc.c (gc_is_heap_obj): Function removed.
(mark_obj_maybe): New static function, with body consisting
of code moved from mark_mem_region.
(mark_mem_region): Moved code replaced by call to mark_obj_maybe.
(gc_conservative_mark): New function, wraps mark_obj_maybe.
* gc.h (gc_conservative_mark): Declared.
(gc_is_heap_obj): Declaration removed.
* parser.c (yy_tok_mark): Use gc_conservative_mark
instead of gc_is_heap_obj check and gc_mark.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The method of inserting a character sequence which generates a
SECRET_TOKEN_E token is being replaced with a purely token based
method.
Because we don't manipulate the input stream, the lexer is not
involved. We don't have to flush its state and deal with the carry-over
of the yy_hold_char.
This comes about because recent changes expose a weakness in the old
scheme. Now that a top-level expression can have the form expr.expr, it
means that the Yacc parser reads one token ahead, to see whether there
is a dot or something else. This lookahead token is discarded. We must
re-create it when we call yyparse again. This re-creation is done by
creating a custom yylex function, which can maintain pushback tokens.
We can prime this array of pushback tokens to generate the
SECRET_TOKEN_E, as well as to re-inject the lookahead symbol that was
thrown away by the previous yyparse. To know which lookahead symbol to
re-inject is simple: the scanner just keeps a copy of the most recent
token that it returns to the parser. When the parser returns, that
token must be the lookahead one.
The tokens we keep now in the parser structure are subject to garbage
collection, and so we must mark them. Since the YYSTYPE union has no
type field, a new API is opened up into the garbage collector to help
implement a conservative GC technique.
* gc.c (gc_is_heap_obj): New function.
* gc.h (gc_is_heap_obj): Declared.
* match.c: Include y.tab.h. This is now needed by any module
that needs to instantiate a parser_t structure, because members
of type YYSTYPE occur in the structure. (parser.h can still be included
without y.tab.h, but only an incomplete declaration for the parser
strucure is then given, and a few functions are not declared.)
* parser.c (yy_tok_mark): New static function.
(parser_mark): Mark the recent token and the pushback tokens.
(parser_common_init): Initialize the recent token, the
pushback tokens, and the pushback stack index.
(pushback_token): New static function.
(prime_parser): hold_byte argument removed. Body considerably
simplified. The catenated stream trick is no longer required.
All we do here is set up two pushback tokens and prime the scanner,
if necessary, so it is in the right start state for Lisp.
* parser.l (YY_DECL): Take over definition of scanning function, renaming
to yylex_impl, so we can implement yylex.
(grammar): Rule which produces SECRET_ESCAPE_E token removed.
(reset_scanner): Function removed.
(yylex): New function.
* parser.h (struct parser): Now only forward-declared unless y.tab.h
has been included. New members, recent_tok, tok_pushback and tok_idx.
(yyset_hold_char): Declared.
(reset_scanner): Declaration removed.
(yylex): Declared (if y.tab.h included).
(prime_parser): Declaration updated.
(prime_scanner): Declared.
* Makefile: express new dependency on existence of y.tab.h of txr.o,
match.o and parser.o.
|
|
|
|
|
|
|
|
| |
* lib.h (struct sym): Remove value member.
* lib.c (make_sym): Don't initialize removed member.
* gc.c (mark_obj): Do not mark removed member.
|
|
|
|
| |
destructor. This can catch some use-after-free errors.
|
|
|
|
| |
out of make_obj into gc.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The issue is that when gc is disabled, the gc function
does nothing. But various code depends on calls to gc()
doing something, like making space available in various
static arrays.
When gc is disabled for long periods, there are issues,
like array overruns.
* gc.c (gc): Must no longer be called at all if gc_enabled is false,
and asserts that it is true. Callers must check the gc_enabled
flag and implement appropriate cases.
(make_obj): Only call gc when gc_enabled is true.
If there is no space in the freshobj array after trying gc,
or gc couldn't be tried because it is disabled, then
schedule a full gc.
(gc_set): If the checkobj array is full, only call gc if gc
is enabled, otherwise schedule a full_gc.
(gc_mutated): Do not assume that the mutobj array has room
for another object; only set the object's generation to -1
and put it into the array if there is room. Similarly to
gc_set, do a gc if there is no room, but if gc is not enabled, then
schedule a full gc.
(gc_wrap): Only call gc if gc_enabled is true, and return t in
that case rathe than nil.
* txr.1: Document return value of sys:gc function.
|
|
|
|
|
|
|
|
|
|
| |
* gc.c (make_obj): Fix regression introduced on 2014-10-18,
released in TXR 100. Because make_obj discontinues
placing objects into the freshobj_array when the full_gc
flag has been set, it is incorrect to allocate another heap
when the free list is exhausted and the freshobj_array
has room remaining. It has room remaining because it is
disused.
|
|
|
|
| |
array after a gc is moved into the gc function.
|
|
|
|
| |
rather than FULL_GC_INTERVAL - 1, since it is pre-incremented.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
* arith.c, arith.h, combi.c, combi.h, debug.c, debug.h, eval.c, eval.h,
filter.c, filter.h, gc.c, gc.h, hash.c, hash.h, lib.c, lib.h,
match.c, match.h, parser.h, rand.c, rand.h, regex.c, regex.h,
signal.c, signal.h, stream.c, stream.h, sysif.c, sysif.h, syslog.c,
syslog.h, txr.c, txr.h, unwind.c, unwind.h, utf8.c, utf8.h:
Update.
* LICENSE, METALICENSE: Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* gc.c (struct fin_reg): New struct type.
(final_list, final_tail, mark_makefresh): New static variables.
(mark_obj): Under generational GC, if make_makefresh is in
effect, set the generation to -1 on all marked objects.
(sweep_one): In an EXTRA_DEBUGGING build, call breakpt
if the object being swept is the one in break_obj.
Under generational GC, place reachable objects that are
in generation -1 the freshobj nursery and assign them to generation 0,
rather than sticking them into the mature generation 1.
(sweep): Under generational gc, reset the freshobj_idx variable
here, so that sweep_one has an empty nursery in which
to place the generation -1 objects.
(prepare_finals, call_finals): New static functions.
(gc): Call prepare_finals before sweep, and call call_finals
just before re-enabling GC and returning. Do not reset freshobj_idx to
zero; this was done in sweep, which may have added entries into it.
(gc_finalize): New function.
(gc_late_init): Register gc_finalize as intrinsic function finalize.
* txr.1: Documented finalize.
* HACKING: Documented finalization, described the additional
meaning of the -1 generation, and added a section on debugging with
break_obj and breakpt.
|
|
|
|
|
|
|
|
|
|
| |
(GREP_CHECK): New macro.
(enforce): Rewritten using GREP_CHECK, with new checks.
* arith.c, combi.c, debug.c, eval.c, filter.c, gc.c, hash.c, lib.c,
* lib.h, match.c, parser.l, parser.y, rand.c, regex.c, signal.c,
* signal.h, stream.c, syslog.c, txr.c, unwind.c, utf8.c: Remove
trailing spaces.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
during a traversal, which could cause items to be visited
twice or skipped.
* gc.c (full_gc): Changed from static to exter (full_gc): Changed to
internal linkage.
* gc.h (full_gc): Declared.
* hash.c (struct hash): New member, usecount.
(struct hash_iter): New member, next.
(reachable_iters): New static variable.
(hash_mark): Reset the usecount of every reachable hash table.
(hash_iter_mark): Add every reachable iterator to reachable_iters
list.
(make_hash, make_similar_hash, copy_hash): Initialize usecount.
(gethash_c): Do not call hash_grow if usecount is nonzero.
(hash_begin): Initialize next field of hash_iter to null.
Increment use count on hash table.
(hash_next): When traversal ends, release use count, and
null out the hash table reference.
(do_weak_tables): New static function.
(do_iters): New static function.
(hash_process_weak): Weak hash processing logic moved
to do_weak_tables. Also calls do_iters.
* txr.1: Describe hash table traversal, and the assurances
and caveats about inserting and deleting items.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
of room. This could happen when parsing a really large TXR program,
since gc is disabled during parsing. Currently it asserts, which
is not acceptable.
* gc.c (make_obj): If after gc, the freshobj array has not been
emptied (obviously because gc is disabled), do not assert.
Rather, set the full_gc flag to request a full garbage collection
when gc is re-enabled. Furthermore, only place newly allocated objects
into freshobj if full_gc has not been set. Thus, if we exhaust the
freshobj array while gc is off, the full_gc flag is set, and we
discontinue use of that array. When gc is re-enabled, we will do a full
gc pass. A full gc pass ignores freshobj array, so it doesn't matter
that its use was discontinued.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
to C++ style casts when compiling as C++.
* lib.h (strip_qual, convert, coerce): New casting macros.
(TAG_MASK, tag, type, wli_noex, auto_str, static_str,
litptr, num_fast, chr, lit_noex, nil, nao): Use cast macros.
* arith.c (mul, isqrt_fixnum, bit): Use cast macros.
* configure (INT_PTR_MAX): Define using cast macro.
* debug.c (debug_init): Use cast macro.
* eval.c (do_eval, expand_macro, reg_op, reg_mac, eval_init):
Use cast macros.
* filter.c (filter_init): Use cast macro.
* gc.c (more, mark_obj, in_heap, mark, sweep_one, unmark): Use
cast macros.
* hash.c (hash_double, equal_hash, eql_hash, hash_equal_op,
hash_hash_op, hash_print_op, hash_mark, make_hash, make_similar_hash,
copy_hash, gethash_c, gethash, gethash_f, gethash_n, remhash,
hash_count, get_hash_userdata, set_hash_userdata, hash_iter_destroy,
hash_iter_mark, hash_begin, hash_uni, hash_diff, hash_isec): Use
cast macros.
* lib.c (code2type, chk_malloc, chk_malloc_gc_more, chk_calloc,
chk_realloc, chk_strdup, num, c_num, string, mkstring, mkustring,
upcase_str, downcase_str, string_extend, sub_str, cat_str, trim_str,
c_chr, vector, vec_set_length, copy_vec, sub_vec, cat_vec,
cobj_print_op, obj_init): Likewise.
* match.c (do_match_line, hv_trampoline, match_files, dir_tables_init):
Likewise.
* parser.l (grammar): Likewise.
* parser.y (parse): Likewise.
* rand.c (make_state, make_random_state, random_fixnum, random):
Likewise.
* regex.c (CHAR_SET_L2_LO, CHAR_SET_L2_HI, CHAR_SET_L1_LO,
CHAR_SET_L1_HI, CHAR_SET_L0_LO, CHAR_SET_L0_HI, L0_full, L0_fill_range,
L1_full, L1_fill_range, L1_contains, L1_free, L2_full, L2_fill_range,
L2_contains, L2_free, L3_fill_range, L3_contains, L3_free,
char_set_create, char_set_cobj_destroy, nfa_state_accept,
nfa_state_empty, nfa_state_single, nfa_state_wild, nfa_state_set,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
(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.
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
| |
(prot1, rel1, mark): Follow rename.
* gc.h (gc_prot_top): Declared.
* signal.h (extended_jmp_buf): New member, gc_pt.
(extended_setjmp): Save and restore gc_prot_top.
|
|
|
|
|
|
|
|
| |
debug.h, eval.c, eval.h, filter.c, filter.h, gc.c, gc.h, hash.c,
hash.h, lib.c, lib.h, match.c, match.h, parser.h, parser.l, parser.y,
rand.c, rand.h, regex.c, regex.h, signal.c, signal.h, stream.c,
stream.h, syslog.c, syslog.h, txr.c, txr.h, unwind.c, unwind.h,
utf8.c, utf8.h: Synchronize license header with LICENSE.
|
|
|
|
| |
headers.
|
|
|
|
|
| |
to 8 * HEAP_SIZE from 2 * HEAP_SIZE to reduce frequency
of garbage collections.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
GC. The issue being solved here is the accuracy of the gc_set function.
The existing impelmentation is too conservative. It has no generation
information about the memory location being stored, and so it assumes
the worst: that it is a location in the middle of a gen 1 object.
This is sub-optimal, creating unacceptable pressure against the
checkobj array and, worse, as a consequence causing unreachable gen 0
objects to be tenured into gen 1.
To solve this problem, we replace "val *" pointers with a structure
of type "loc" which keeps track of the object too, which lets us
discover the generation.
I tried another approach: using just a pointer with a bitfield
indicating the generation. This turned out to have a serious issue:
such a bitfield goes stale when the object is moved to a different
generation. The object holding the memory location is in gen 1, but the
annotated pointer still indicates gen 0. The gc_set function then
makes the wrong decision, and premature reclamation takes place.
* combi.c (perm_init_common, comb_gen_fun_common,
rcomb_gen_fun_common, rcomb_list_gen_fun): Update to new interfaces
for managing mutation.
* debug.c (debug): Update to new interfaces for managing mutation.
Avoid loc variable name.
* eval.c (env_fbind, env_fbind): Update to new interfaces
for managing mutation.
(lookup_var_l, dwim_loc): Return loc type and update to new interfaces.
(apply_frob_args, op_modplace, op_dohash, transform_op, mapcarv,
mappendv, repeat_infinite_func, repeat_times_func): Update to new
interfaces for managing mutation.
* eval.h (lookup_var_l): Declaration updated.
* filter.c (trie_add, trie_compress, trie_compress_intrinsic,
* build_filter, built_filter_from_list, filter_init): Update to new
* interfaces.
* gc.c (gc_set): Rewritten to use loc type which provides the exact
generation. We do not need the in_malloc_range hack any more, since
we have the backpointer to the object.
(gc_push): Take loc rather than raw pointer.
* gc.h (gc_set, gc_push): Declarations updated.
* hash.c (struct hash): The acons* functions use loc instead
of val * now.
(hash_equal_op, copy_hash, gethash_c, inhash, gethash_n, pushhash,
Change to how locations are passed around, for the sake of generational
GC. The issue being solved here is the accuracy of the gc_set function.
The existing impelmentation is too conservative. It has no generation
information about the memory location being stored, and so it assumes
the worst: that it is a location in the middle of a gen 1 object.
This is sub-optimal, creating unacceptable pressure against the
checkobj array and, worse, as a consequence causing unreachable gen 0
objects to be tenured into gen 1.
To solve this problem, we replace "val *" pointers with a structure
of type "loc" which keeps track of the object too, which lets us
discover the generation.
I tried another approach: using just a pointer with a bitfield
indicating the generation. This turned out to have a serious issue:
such a bitfield goes stale when the object is moved to a different
generation. The object holding the memory location is in gen 1, but the
annotated pointer still indicates gen 0. The gc_set function then
makes the wrong decision, and premature reclamation takes place.
* combi.c (perm_init_common, comb_gen_fun_common,
rcomb_gen_fun_common, rcomb_list_gen_fun): Update to new interfaces
for managing mutation.
* debug.c (debug): Update to new interfaces for managing mutation.
Avoid loc variable name.
* eval.c (env_fbind, env_fbind): Update to new interfaces
for managing mutation.
(lookup_var_l, dwim_loc): Return loc type and update to new interfaces.
(apply_frob_args, op_modplace, op_dohash, transform_op, mapcarv,
mappendv, repeat_infinite_func, repeat_times_func): Update to new
interfaces for managing mutation.
* eval.h (lookup_var_l): Declaration updated.
* filter.c (trie_add, trie_compress, trie_compress_intrinsic,
* build_filter, built_filter_from_list, filter_init): Update to new
* interfaces.
* gc.c (gc_set): Rewritten to use loc type which provides the exact
generation. We do not need the in_malloc_range hack any more, since
we have the backpointer to the object.
(gc_push): Take loc rather than raw pointer.
* gc.h (gc_set, gc_push): Declarations updated.
* hash.c (struct hash): The acons* functions use loc instead
of val * now.
(hash_equal_op, copy_hash, gethash_c, inhash, gethash_n, pushhash,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|