diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-11-01 20:27:42 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-11-01 20:27:42 -0700 |
commit | 1a71176dca92298cbb4e93530be2a79c80956471 (patch) | |
tree | 67c9b7e0d943cf26f89776b58c3b5060ed48f073 | |
parent | fcd748480a76b3fef7586483b29fc5281e405e1f (diff) | |
download | txr-1a71176dca92298cbb4e93530be2a79c80956471.tar.gz txr-1a71176dca92298cbb4e93530be2a79c80956471.tar.bz2 txr-1a71176dca92298cbb4e93530be2a79c80956471.zip |
lib: use stack-allocated hash iterators everywhere.
* eval.c (op_dohash): Use hash_iter instead of consing up
heap-allocated hash iterator.
* filter.c (trie_compress, regex_from_trie): Likewise.
* hash.c (hash_equal_op, hash_hash_op, hash_print_op):
Likewise.
* lib.c (package_local_symbols, package_foreign_symbols,
find_max, find_if, rfind_if, populate_obj_hash): Likewise.
* parser.c (circ_backpatch, get_visible_syms): Likewise.
* struct.c (method_name, get_slot_syms): Likewise.
-rw-r--r-- | eval.c | 7 | ||||
-rw-r--r-- | filter.c | 18 | ||||
-rw-r--r-- | hash.c | 23 | ||||
-rw-r--r-- | lib.c | 40 | ||||
-rw-r--r-- | parser.c | 13 | ||||
-rw-r--r-- | struct.c | 12 |
6 files changed, 72 insertions, 41 deletions
@@ -2488,21 +2488,24 @@ static val op_for(val form, val env) static val op_dohash(val form, val env) { + val op = first(form); val spec = second(form); val keysym = first(spec); val valsym = second(spec); val hashform = third(spec); val resform = fourth(spec); val body = rest(rest(form)); - val iter = hash_begin(eval(hashform, env, hashform)); val keyvar = cons(keysym, nil); val valvar = cons(valsym, nil); val new_env = make_env(cons(keyvar, cons(valvar, nil)), nil, env); val cell; + struct hash_iter hi; + + hash_iter_init(&hi, eval(hashform, env, hashform), op); uw_block_begin (nil, result); - while ((cell = hash_next(iter)) != nil) { + while ((cell = hash_iter_next(&hi)) != nil) { /* These assignments are gc-safe, because keyvar and valvar are newer objects than existing entries in the hash, unless the body mutates hash by inserting newer objects, @@ -94,14 +94,15 @@ static void trie_compress(loc ptrie) if (zerop(count)) { set(ptrie, value); } else if (count == one && nilp(value)) { - val iter = hash_begin(trie); - val cell = hash_next(iter); + struct hash_iter hi; + val cell = (us_hash_iter_init(&hi, trie), hash_iter_next(&hi)); set(ptrie, cons(us_car(cell), us_cdr(cell))); trie_compress(cdr_l(deref(ptrie))); } else { - val cell, iter = hash_begin(trie); - - for (cell = hash_next(iter); cell; cell = hash_next(iter)) + val cell; + struct hash_iter hi; + us_hash_iter_init(&hi, trie); + for (cell = hash_iter_next(&hi); cell; cell = hash_iter_next(&hi)) trie_compress(mkloc(*us_cdr_p(cell), cell)); } } else if (consp(trie)) { @@ -146,9 +147,12 @@ static val regex_from_trie(val trie) return nil; } else { list_collect_decl (out, ptail); - val iter = hash_begin(trie); val cell; - while ((cell = hash_next(iter)) != nil) { + struct hash_iter hi; + + us_hash_iter_init(&hi, trie); + + while ((cell = hash_iter_next(&hi)) != nil) { val rx = regex_from_trie(us_cdr(cell)); ptail = list_collect(ptail, if3(consp(rx) && car(rx) == compound_s, @@ -374,9 +374,10 @@ static val hash_equal_op(val left, val right) uses_or2; struct hash *l = coerce(struct hash *, left->co.handle); struct hash *r = coerce(struct hash *, right->co.handle); - val liter, riter, lcell, rcell; + val lcell, rcell; val free_conses = nil; val pending = nil; + struct hash_iter lhi, rhi; if (l->hops != r->hops) return nil; @@ -390,10 +391,10 @@ static val hash_equal_op(val left, val right) if (l->count == 0) return t; - liter = hash_begin(left); - riter = hash_begin(right); + us_hash_iter_init(&lhi, left); + us_hash_iter_init(&rhi, right); - while ((lcell = hash_next(liter)) && ((rcell = hash_next(riter)))) { + while ((lcell = hash_iter_next(&lhi)) && ((rcell = hash_iter_next(&rhi)))) { val ncons = or2(pop(&free_conses), cons(nil, nil)); val found; @@ -460,7 +461,8 @@ static ucnum hash_hash_op(val obj, int *count, ucnum seed) { ucnum out = 0; struct hash *h = coerce(struct hash *, obj->co.handle); - val iter, cell; + val cell; + struct hash_iter hi; if ((*count)-- <= 0) return 0; @@ -475,9 +477,9 @@ static ucnum hash_hash_op(val obj, int *count, ucnum seed) out += equal_hash(h->userdata, count, seed); out &= NUM_MAX; - iter = hash_begin(obj); + us_hash_iter_init(&hi, obj); - while ((*count)-- > 0 && (cell = hash_next(iter)) != nil) { + while ((*count)-- > 0 && (cell = hash_iter_next(&hi)) != nil) { out += equal_hash(cell, count, seed); out &= NUM_MAX; } @@ -541,11 +543,14 @@ static void hash_print_op(val hash, val out, val pretty, struct strm_ctx *ctx) } put_char(chr(')'), out); { - val iter = hash_begin(hash), cell; + val cell; + struct hash_iter hi; cnum max_len = ctx->strm->max_length; cnum max_count = max_len; - while ((cell = hash_next(iter))) { + us_hash_iter_init(&hi, hash); + + while ((cell = hash_iter_next(&hi))) { val key = us_car(cell); val value = us_cdr(cell); if (width_check(out, chr(' '))) @@ -5181,10 +5181,12 @@ val package_local_symbols(val package_in) { val package = get_package(lit("package-local-symbols"), package_in, t); list_collect_decl (out, ptail); - val hiter = hash_begin(package->pk.symhash); + struct hash_iter hi; val cell; - while ((cell = hash_next(hiter))) { + us_hash_iter_init(&hi, package->pk.symhash); + + while ((cell = hash_iter_next(&hi))) { val sym = us_cdr(cell); if (symbol_package(sym) == package) ptail = list_collect(ptail, sym); @@ -5197,10 +5199,12 @@ val package_foreign_symbols(val package_in) { val package = get_package(lit("package-foreign-symbols"), package_in, t); list_collect_decl (out, ptail); - val hiter = hash_begin(package->pk.symhash); + struct hash_iter hi; val cell; - while ((cell = hash_next(hiter))) { + us_hash_iter_init(&hi, package->pk.symhash); + + while ((cell = hash_iter_next(&hi))) { val sym = us_cdr(cell); if (symbol_package(sym) != package) ptail = list_collect(ptail, sym); @@ -9034,12 +9038,12 @@ val find_max(val seq, val testfun, val keyfun) return nil; case SEQ_HASHLIKE: { - val hiter = hash_begin(si.obj); - val cell = hash_next(hiter); + struct hash_iter hi; + val cell = (hash_iter_init(&hi, si.obj, self), hash_iter_next(&hi)); val maxelt = cell; val maxkey = if2(cell, funcall1(keyfun, cell)); - while (cell && (cell = hash_next(hiter))) { + while (cell && (cell = hash_iter_next(&hi))) { val key = funcall1(keyfun, cell); if (funcall2(testfun, key, maxkey)) { maxkey = key; @@ -9113,10 +9117,12 @@ val find_if(val pred, val seq, val key) break; case SEQ_HASHLIKE: { - val hiter = hash_begin(si.obj); + struct hash_iter hi; val cell; - while ((cell = hash_next(hiter))) { + hash_iter_init(&hi, si.obj, self); + + while ((cell = hash_iter_next(&hi))) { val key = funcall1(keyfun, cell); if (funcall1(pred, key)) return cell; @@ -9172,10 +9178,12 @@ val rfind_if(val predi, val seq, val key) break; case SEQ_HASHLIKE: { - val hiter = hash_begin(si.obj); + struct hash_iter hi; val cell; - while ((cell = hash_next(hiter))) { + hash_iter_init(&hi, si.obj, self); + + while ((cell = hash_iter_next(&hi))) { val key = funcall1(keyfun, cell); if (funcall1(predi, key)) found = cell; @@ -11911,9 +11919,10 @@ tail: } case COBJ: if (hashp(obj)) { - val iter = hash_begin(obj); + struct hash_iter hi; val cell; - while ((cell = hash_next(iter))) { + us_hash_iter_init(&hi, obj); + while ((cell = hash_iter_next(&hi))) { populate_obj_hash(us_car(cell), ctx); populate_obj_hash(us_cdr(cell), ctx); } @@ -11949,9 +11958,10 @@ tail: static void obj_hash_merge(val parent_hash, val child_hash) { val self = lit("print"); - val iter, cell; + struct hash_iter hi; + val cell; - for (iter = hash_begin(child_hash); (cell = hash_next(iter));) { + for (us_hash_iter_init(&hi, child_hash); (cell = hash_iter_next(&hi));) { val new_p; loc pcdr = gethash_l(self, parent_hash, us_car(cell), mkcloc(new_p)); if (new_p) @@ -372,11 +372,13 @@ tail: circ_backpatch(p, &cs, u); if (old_circ_count > 0) { - val iter = hash_begin(obj); val cell; val pairs = nil; + struct hash_iter hi; - while ((cell = hash_next(iter))) { + us_hash_iter_init(&hi, obj); + + while ((cell = hash_iter_next(&hi))) { circ_backpatch(p, &cs, cell); push(cell, &pairs); } @@ -836,10 +838,13 @@ static val get_visible_syms(val package, int include_fallback) for (; fblist; fblist = cdr(fblist)) { val fb_pkg = car(fblist); - val hiter = hash_begin(fb_pkg->pk.symhash); val fcell; val new_p; - while ((fcell = hash_next(hiter))) { + struct hash_iter hi; + + us_hash_iter_init(&hi, fb_pkg->pk.symhash); + + while ((fcell = hash_iter_next(&hi))) { loc pcdr = gethash_l(lit("listener"), symhash, us_car(fcell), mkcloc(new_p)); if (new_p) set(pcdr, us_cdr(fcell)); @@ -1649,10 +1649,12 @@ static val struct_inst_equalsub(val obj) val method_name(val fun) { - val sth_iter = hash_begin(struct_type_hash); + struct hash_iter sthi; val sth_cell; - while ((sth_cell = hash_next(sth_iter))) { + us_hash_iter_init(&sthi, struct_type_hash); + + while ((sth_cell = hash_iter_next(&sthi))) { val sym = us_car(sth_cell); val stype = us_cdr(sth_cell); val sl_iter; @@ -1695,10 +1697,12 @@ val method_name(val fun) val get_slot_syms(val package, val is_current, val method_only) { val result_hash = make_hash(nil, nil, nil); - val sth_iter = hash_begin(struct_type_hash); + struct hash_iter sthi; val sth_cell; - while ((sth_cell = hash_next(sth_iter))) { + us_hash_iter_init(&sthi, struct_type_hash); + + while ((sth_cell = hash_iter_next(&sthi))) { val stype = us_cdr(sth_cell); val sl_iter; struct struct_type *st = coerce(struct struct_type *, stype->co.handle); |