// There are two requirements to perform a GC:
//
// 1. We can't be profiling, since profiling relies on the redundant heap
//    entries. When profiling we set disable_gc.
// 2. We must be able to access all roots.
//
// We track as many roots as possible, and eventually aim to track them all, but
// for the moment we're only sure we have all roots when we are in the module
// evaluation eval. There are three roots we don't yet know about:
//
// 1. When evaluating an expression which has multiple subexpressions, e.g. List
//    we can't GC during that, as we can't see the root of the first list.
// 2. When evaluating inside a native function, especially if that native
//    function calls back to a non-native function, e.g. sort with a comparison
//    function.
// 3. When iterating we freeze the iteration variable, which means it
//    can't be moved by a GC. A special type of root.
//
// The first issue can be solved by moving to a bytecode interpreter and
// evaluation stack. The second issue can be solved by disabling GC while in
// such functions (it's probably rare). The third issue could be solved by
// making the freeze for iteration a separate flag to the RefCell, at the cost
// of an extra word in ValueMem. Or we could disable GC while iterating.
//
// For the moment we only GC when executing a statement at the root of the
// module, which we know is safe with respect to all three conditions.
//
// We also require that `extra_v` is None, since otherwise the user might have
// additional values stashed somewhere.
There are two requirements to perform a GC:
1. We can't be profiling, since profiling relies on the redundant heap
entries. When profiling we set disable_gc.
2. We must be able to access all roots.

We track as many roots as possible, and eventually aim to track them all, but
for the moment we're only sure we have all roots when we are in the module
evaluation eval. There are three roots we don't yet know about.

1. When evaluating an expression which has multiple subexpressions, e.g. List
we can't GC during that, as we can't see the root of the first list.
2. When evaluating inside a native function, especially if that native
function calls back to a non-native function, e.g. sort with a comparison
function.
3. When iterating we freeze the iteration variable, which means it
can't be moved by a GC. A special type of root.

The first issue can be solved by moving to a bytecode interpreter and
evaluation stack. The second issue can be solved by disabling GC while in
such functions (it's probably rare). The third issue could be solved by
making the freeze for iteration a separate flag to the RefCell, at the cost
of an extra word in ValueMem. Or we could disable GC while iterating.

For the moment we only GC when executing a statement at the root of the
module, which we know is safe with respect to all three conditions.

We also require that `extra_v` is None, since otherwise the user might have
additional values stashed somewhere.
There are two requirements to perform a GC : 1 . We can ' t be profiling since profiling relies on the redundant heap entries . When profiling we set disable_gc . 2 . We must be able to access all roots . We track as many roots as possible and eventually aim to track them all but for the moment we ' re only sure we have all roots when we are in the module evaluation eval . There are three roots we don ' t yet know about . 1 . When evaluating an expression which has multiple subexpressions e . g . List we can ' t GC during that as we can ' t see the root of the first list . 2 . When evaluating inside a native function especially if that native function calls back to a non - native function e . g . sort with a comparison function . 3 . When iterating we freeze the iteration variable which means it can ' t be moved by a GC . A special type of root . The first issue can be solved by moving to a bytecode interpreter and evaluation stack . The second issue can be solved by disabling GC while in such functions ( it ' s probably rare ) . The third issue could be solved by making the freeze for iteration a separate flag to the RefCell at the cost of an extra word in ValueMem . Or we could disable GC while iterating . For the moment we only GC when executing a statement at the root of the module which we know is safe with respect to all three conditions . We also require that ` extra_v ` is None since otherwise the user might have additional values stashed somewhere .
fn possible_gc(eval: &mut Evaluator) {
    if !eval.disable_gc
        && eval.heap().allocated_bytes() >= eval.next_gc_level
        && eval.extra_v.is_none()
    {
        eval.ann("garbage_collection", |eval| {
            // When we are at a module scope (as checked above) the eval contains
            // references to all values, so walking covers everything and the unsafe
            // is satisfied.
            unsafe {
                eval.heap().garbage_collect(|tracer| eval.trace(tracer))
            }
            eval.next_gc_level = eval.heap().allocated_bytes() + GC_THRESHOLD;
        })
    }
}
fn possible_gc ( eval : & mut Evaluator ) { if ! eval . disable_gc && eval . heap ( ) . allocated_bytes ( ) >= eval . next_gc_level && eval . extra_v . is_none ( ) { eval . ann ( " " , | eval | { // When we are at a module scope (as checked above) the eval contains // references to all values, so walking covers everything and the unsafe // is satisfied. unsafe { eval . heap ( ) . garbage_collect ( | tracer | eval . trace ( tracer ) ) } eval . next_gc_level = eval . heap ( ) . allocated_bytes ( ) + GC_THRESHOLD ; } ) } }
There are two requirements to perform a GC:
1.
There are two requirements to perform a GC : 1 .
eval
&mut Evaluator