summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-11-01 20:27:42 -0700
committerKaz Kylheku <kaz@kylheku.com>2019-11-01 20:27:42 -0700
commit1a71176dca92298cbb4e93530be2a79c80956471 (patch)
tree67c9b7e0d943cf26f89776b58c3b5060ed48f073
parentfcd748480a76b3fef7586483b29fc5281e405e1f (diff)
downloadtxr-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.c7
-rw-r--r--filter.c18
-rw-r--r--hash.c23
-rw-r--r--lib.c40
-rw-r--r--parser.c13
-rw-r--r--struct.c12
6 files changed, 72 insertions, 41 deletions
diff --git a/eval.c b/eval.c
index 837e20e2..84f1dc41 100644
--- a/eval.c
+++ b/eval.c
@@ -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,
diff --git a/filter.c b/filter.c
index ce03f575..725939ae 100644
--- a/filter.c
+++ b/filter.c
@@ -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,
diff --git a/hash.c b/hash.c
index 03c03436..177e639b 100644
--- a/hash.c
+++ b/hash.c
@@ -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(' ')))
diff --git a/lib.c b/lib.c
index 98bb672d..18764ad7 100644
--- a/lib.c
+++ b/lib.c
@@ -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)
diff --git a/parser.c b/parser.c
index c303f9e1..a0c51292 100644
--- a/parser.c
+++ b/parser.c
@@ -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));
diff --git a/struct.c b/struct.c
index 956506d2..a8d1f373 100644
--- a/struct.c
+++ b/struct.c
@@ -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);