summaryrefslogtreecommitdiffstats
path: root/combi.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-03-29 11:44:52 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-03-29 22:55:55 -0700
commitc61ccd9769c9c83dcdf5f7693af2ca0a605b6e19 (patch)
tree6e9cfead5209cc2c591f472d8c884bf5fe9563ce /combi.c
parentc20c994098c12f499fd24a89305ff37c7a2bcf76 (diff)
downloadtxr-c61ccd9769c9c83dcdf5f7693af2ca0a605b6e19.tar.gz
txr-c61ccd9769c9c83dcdf5f7693af2ca0a605b6e19.tar.bz2
txr-c61ccd9769c9c83dcdf5f7693af2ca0a605b6e19.zip
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, 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,
Diffstat (limited to 'combi.c')
-rw-r--r--combi.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/combi.c b/combi.c
index 24061b2a..740aedd0 100644
--- a/combi.c
+++ b/combi.c
@@ -105,10 +105,10 @@ static val perm_init_common(val p, val k_null)
} else {
val state = vector(three, nil);
val c = vector(k, zero);
- set(*vecref_l(state, zero), p);
- set(*vecref_l(state, one), k);
- set(*vecref_l(state, two), c);
- *vecref_l(c, negone) = negone;
+ set(vecref_l(state, zero), p);
+ set(vecref_l(state, one), k);
+ set(vecref_l(state, two), c);
+ deref(vecref_l(c, negone)) = negone;
return state;
}
}
@@ -355,7 +355,7 @@ static void comb_gen_fun_common(val state)
val curr = first(iter);
val curr_rest = rest(curr);
if (curr_rest != prev && consp(curr_rest)) {
- set(*car_l(iter), curr_rest);
+ set(car_l(iter), curr_rest);
return;
} else if (rest(iter)) {
val next = second(iter);
@@ -363,11 +363,11 @@ static void comb_gen_fun_common(val state)
val next_rest_rest = rest(next_rest);
prev = curr;
if (next_rest != curr && consp(next_rest_rest))
- prev = set(*car_l(iter), next_rest_rest);
- }
+ prev = set(car_l(iter), next_rest_rest);
+ }
}
- *car_l(state) = nil;
+ deref(car_l(state)) = nil;
}
static val comb_list_gen_fun(val state)
@@ -516,16 +516,16 @@ static void rcomb_gen_fun_common(val state)
if (consp(curr_rest)) {
val jter;
for (jter = state; jter != next; jter = cdr(jter))
- set(*car_l(jter), curr_rest);
+ set(car_l(jter), curr_rest);
return;
} else if (next) {
val next = second(iter);
if (curr != next)
- set(*car_l(iter), rest(next));
+ set(car_l(iter), rest(next));
}
}
- *car_l(state) = nil;
+ deref(car_l(state)) = nil;
}
static val rcomb_list_gen_fun(val state)