- unsigned long t_before_gc = 0;
-
- scm_i_thread_put_to_sleep ();
-
- scm_c_hook_run (&scm_before_gc_c_hook, 0);
-
-#ifdef DEBUGINFO
- fprintf (stderr,"gc reason %s\n", what);
- fprintf (stderr,
- scm_is_null (*SCM_FREELIST_LOC (scm_i_freelist))
- ? "*"
- : (scm_is_null (*SCM_FREELIST_LOC (scm_i_freelist2)) ? "o" : "m"));
-#endif
-
- t_before_gc = scm_c_get_internal_run_time ();
- scm_gc_malloc_collected = 0;
-
- /*
- Set freelists to NULL so scm_cons () always triggers gc, causing
- the assertion above to fail.
- */
- *SCM_FREELIST_LOC (scm_i_freelist) = SCM_EOL;
- *SCM_FREELIST_LOC (scm_i_freelist2) = SCM_EOL;
-
- /*
- Let's finish the sweep. The conservative GC might point into the
- garbage, and marking that would create a mess.
- */
- scm_i_sweep_all_segments ("GC", &scm_i_gc_sweep_stats);
- scm_check_deprecated_memory_return ();
-
-#if (SCM_DEBUG_CELL_ACCESSES == 0 && SCM_SIZEOF_UNSIGNED_LONG ==4)
- /* Sanity check our numbers. */
- /* TODO(hanwen): figure out why the stats are off on x64_64. */
- /* If this was not true, someone touched mark bits outside of the
- mark phase. */
- assert (scm_cells_allocated == scm_i_marked_count ());
- assert (scm_i_gc_sweep_stats.swept
- == (scm_i_master_freelist.heap_total_cells
- + scm_i_master_freelist2.heap_total_cells));
- assert (scm_i_gc_sweep_stats.collected + scm_cells_allocated
- == scm_i_gc_sweep_stats.swept);
-#endif /* SCM_DEBUG_CELL_ACCESSES */
-
- /* Mark */
- scm_c_hook_run (&scm_before_mark_c_hook, 0);
-
- scm_mark_all ();
- scm_gc_mark_time_taken += (scm_c_get_internal_run_time () - t_before_gc);
-
- scm_cells_allocated = scm_i_marked_count ();
-
- /* Sweep
-
- TODO: the after_sweep hook should probably be moved to just before
- the mark, since that's where the sweep is finished in lazy
- sweeping.
-
- MDJ 030219 <djurfeldt@nada.kth.se>: No, probably not. The
- original meaning implied at least two things: that it would be
- called when
-
- 1. the freelist is re-initialized (no evaluation possible, though)
-
- and
-
- 2. the heap is "fresh"
- (it is well-defined what data is used and what is not)
-
- Neither of these conditions would hold just before the mark phase.
-
- Of course, the lazy sweeping has muddled the distinction between
- scm_before_sweep_c_hook and scm_after_sweep_c_hook, but even if
- there were no difference, it would still be useful to have two
- distinct classes of hook functions since this can prevent some
- bad interference when several modules adds gc hooks.
- */
- scm_c_hook_run (&scm_before_sweep_c_hook, 0);
-
- /*
- Nothing here: lazy sweeping.
- */
- scm_i_reset_segments ();
-
- *SCM_FREELIST_LOC (scm_i_freelist) = SCM_EOL;
- *SCM_FREELIST_LOC (scm_i_freelist2) = SCM_EOL;
-
- /* Invalidate the freelists of other threads. */
- scm_i_thread_invalidate_freelists ();
-
- scm_c_hook_run (&scm_after_sweep_c_hook, 0);
-
- gc_end_stats ();
-
- scm_i_gc_sweep_stats.collected = scm_i_gc_sweep_stats.swept = 0;
- scm_i_gc_sweep_freelist_reset (&scm_i_master_freelist);
- scm_i_gc_sweep_freelist_reset (&scm_i_master_freelist2);
-
- /* Arguably, this statistic is fairly useless: marking will dominate
- the time taken.
- */
- scm_gc_time_taken += (scm_c_get_internal_run_time () - t_before_gc);
-
- scm_i_thread_wake_up ();
- /*
- For debugging purposes, you could do
- scm_i_sweep_all_segments ("debug"), but then the remains of the
- cell aren't left to analyse.
- */