summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2012-04-05 09:18:14 -0700
committerKaz Kylheku <kaz@kylheku.com>2012-04-05 09:18:14 -0700
commitc162f73f9cfd0bb48675dc11bd56ac359451510b (patch)
tree5fda9e1835758135d39090ddc8ca79ec1070c5d9 /eval.c
parent1e5d313bafa78885490b3fa0759ba76436917d9b (diff)
downloadtxr-c162f73f9cfd0bb48675dc11bd56ac359451510b.tar.gz
txr-c162f73f9cfd0bb48675dc11bd56ac359451510b.tar.bz2
txr-c162f73f9cfd0bb48675dc11bd56ac359451510b.zip
The mut macro should only be used for vectors or vector-like objects
which hold direct references to other objects and must be used each time a mutation takes place. * eval.c (op_dohash): invocations of mut macro removed. Comment rewritten. * lib.c (sort_list): Use set macro for mutating assignment. Do not invoke mut on sorted list; it won't work anyway, because it doesn't mean what the code wants it to mean: that the list will be fully traversed during gc marking.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c16
1 files changed, 6 insertions, 10 deletions
diff --git a/eval.c b/eval.c
index 4a44c194..32be8f2f 100644
--- a/eval.c
+++ b/eval.c
@@ -1035,17 +1035,13 @@ static val op_dohash(val form, val env)
uw_block_begin (nil, result);
- /*
- * Avoid issuing set() operations in the loop;
- * just tell GC that these variables are being mutated.
- * TODO: This is not enough since gc can take place while we execute this
- * loop. What we need is to conditionally re-establish this.
- * GC needs to provide a way to let us know "has GC happened since ..."
- */
- mut(keyvar);
- mut(valvar);
-
while ((cell = hash_next(&iter)) != 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,
+ and also deleting them such that these variables end up
+ with the only reference. But in that case, those objects
+ will be noted in the GC's check list. */
*cdr_l(keyvar) = car(cell);
*cdr_l(valvar) = cdr(cell);
eval_progn(body, new_env, form);