diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2018-11-06 06:55:16 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2018-11-06 06:55:16 -0800 |
commit | e1b237fde9327eceab3ef1640ccab6c2b37fb9f1 (patch) | |
tree | bf813b0f2618340ef7002b4dde71dcdedc061742 /struct.c | |
parent | 27ced6b531c120a3e77105659bb1b7aef39b961b (diff) | |
download | txr-e1b237fde9327eceab3ef1640ccab6c2b37fb9f1.tar.gz txr-e1b237fde9327eceab3ef1640ccab6c2b37fb9f1.tar.bz2 txr-e1b237fde9327eceab3ef1640ccab6c2b37fb9f1.zip |
gc: eliminate most uses of gc_mutated.
The code is using gc_mutated in situations that resemble
assignment: a value is stored into a slot in some object.
These situations should be handled using the same logic as
embodied in the gc_set function. This is because gc_set will
consider both objects, and in many cases will not have to do
anything special. E.g. if an immature object is stored into
another immature object, or mature into immature, or mature
into mature. Whereas gc_mutated is a "just in case" function
which forces the garbage collector to traverse the indicated
object, if that object is mature.
In this patch we refactor gc_set to expose its underlying
logic with a somewhat more flexible function called
gc_assign_check. We put that behind a conditionally defined
macro called setcheck, and then use that to replace
invocations of the mut macro in various places.
The only uses of gc_mutated that remain are in the bulk
vector assignment and copy_struct: operations in which
potentially many element values are migrated from one
aggregate object to another, making it potentially expensive
to do individual assignment checks.
* gc.c (gc_assign_check): New function, formed from guts of
gc_set.
(gc_set): Now a trivial function, implemented via call to
gc_assign_check.
* gc.h (gc_assign_check): Declared.
* lib.c (cons): Use setcheck instead of gc_mutated, since we
are storing only two values into the existing cons: the car
and the cdr.
* struct.c (clear_struct): Use setcheck instead of gc_mutated,
since we are just storing one value into the structure, the
clear_val. The fact that we are storing it into multiple slots
is irrelevant.
* vm.c (vm_make_closure): Use setcheck instead of mut, using
the new heap_vector as the child object with regard to the
closure. Rationale: the only threat here is that when we
allocate the heap vector, a GC is triggered which pushes the
closure into the mature generation. Then the store of the heap
vector into the closure is a wrong-way reference, with regard
to generational GC. The elements in the vector are immaterial;
they are older than both the closure and the vector, therefore
their relationship to either object is a right-way reference.
(vm_set, vm_sm_set): Replace mut by a setcheck between the
vector from the display and the new value being stored in it.
(vm_stab): Replace the gc_mutated check, which should have
been a mut macro call, with a setcheck between the vm, and the
binding being stored into the table. The gc_mutated should
have been wrapped with an #if CONFIG_GEN_GC so we are fixing
a build bug here: the code would have prevented TXR from being
built with the generational GC disabled.
Diffstat (limited to 'struct.c')
-rw-r--r-- | struct.c | 2 |
1 files changed, 1 insertions, 1 deletions
@@ -697,7 +697,7 @@ val clear_struct(val strct, val value) for (i = 0; i < st->nslots; i++) si->slot[i] = clear_val; - mut(strct); + setcheck(strct, clear_val); return strct; } |