summaryrefslogtreecommitdiff
path: root/libguile/gc-mark.c
diff options
context:
space:
mode:
authorMarius Vollmer <mvo@zagadka.de>2005-07-31 23:04:36 +0000
committerMarius Vollmer <mvo@zagadka.de>2005-07-31 23:04:36 +0000
commit06c1d90009bd20b0e68243b116f660789094c14a (patch)
tree6d9212df502da5dbc41abdbc2a3fd7f80ad2d858 /libguile/gc-mark.c
parent5070fd11b2975d34df227d7175890ddeed15e1a8 (diff)
downloadguile-06c1d90009bd20b0e68243b116f660789094c14a.tar.gz
* gc-mark.c (scm_mark_all): Do not rely on hooks to run the weak
hashtable and guardian machinery but call the relevant functions directly. * guardians.h, guardians.c, deprecated.h, deprecated.c (scm_destroy_guardian_x, scm_guardian_greedy_p, scm_guardian_destroyed_p, scm_guard, scm_get_one_zombie): Deprecated and moved into deprecated.[ch]. * guardians.h, guardians.c: Mostly rewritten. (scm_i_init_guardians_for_gc, scm_i_identify_inaccessible_guardeds, scm_i_mark_inaccessible_guardeds): New. * weaks.h, weaks.c (SCM_I_WVECT_TYPE, SCM_I_SET_WVECT_TYPE): New. (SCM_I_WVECT_N_ITEMS, SCM_I_SET_WVECT_N_ITEMS): New. (SCM_WVECTF_NOSCAN, SCM_WVECT_NOSCAN_P): Removed. (scm_weaks_prehistory): Removed. (scm_i_init_weak_vectors_for_gc, scm_i_mark_weak_vector, scm_i_mark_weak_vectors_non_weaks, scm_i_remove_weaks_from_weak_vectors, scm_i_remove_weaks): New. (scm_weak_vector_gc_init, scm_mark_weak_vector_spines, scm_scan_weak_vectors): Removed. * hashtab.h (scm_i_scan_weak_hashtables): New. * hashtab.c (make_hash_table, scm_i_rehash): Do not use SCM_WVECTF_NOSCAN. (hashtable_print): Use SCM_HASHTABLE_N_ITEMS instead of t->n_items. (scan_weak_hashtables, scm_i_scan_weak_hashtables): Renamed former to latter. Do not scan the alists themselves, this is done by the weak vector code now. Just update the element count. * vectors.h (SCM_I_WVECT_TYPE, SCM_I_WVECT_EXTRA): Renamed former to latter. The type is now only part of the cell word. (SCM_I_SET_WVECT_TYPE, SCM_I_SET_WVECT_EXTRA): Likewise. * init.c (scm_i_init_guile): Do not call scm_weaks_prehistory.
Diffstat (limited to 'libguile/gc-mark.c')
-rw-r--r--libguile/gc-mark.c117
1 files changed, 55 insertions, 62 deletions
diff --git a/libguile/gc-mark.c b/libguile/gc-mark.c
index ad805bfaf..78137af86 100644
--- a/libguile/gc-mark.c
+++ b/libguile/gc-mark.c
@@ -50,6 +50,7 @@ extern unsigned long * __libc_ia64_register_backing_store_base;
#include "libguile/validate.h"
#include "libguile/deprecation.h"
#include "libguile/gc.h"
+#include "libguile/guardians.h"
#ifdef GUILE_DEBUG_MALLOC
#include "libguile/debug-malloc.h"
@@ -70,7 +71,9 @@ void
scm_mark_all (void)
{
long j;
-
+
+ scm_i_init_weak_vectors_for_gc ();
+ scm_i_init_guardians_for_gc ();
scm_i_clear_mark_space ();
@@ -95,11 +98,55 @@ scm_mark_all (void)
}
}
+ scm_mark_subr_table ();
+
+ int loops = 0;
+ while (1)
+ {
+ loops++;
+ int again;
+
+ /* Mark the non-weak references of weak vectors. For a weak key
+ alist vector, this would mark the values for keys that are
+ marked. We need to do this in a loop until everything
+ settles down since the newly marked values might be keys in
+ other weak key alist vectors, for example.
+ */
+ again = scm_i_mark_weak_vectors_non_weaks ();
+ if (again)
+ continue;
+
+ /* Now we scan all marked guardians and move all unmarked objects
+ from the accessible to the inaccessible list.
+ */
+ scm_i_identify_inaccessible_guardeds ();
+
+ /* When we have identified all inaccessible objects, we can mark
+ them.
+ */
+ again = scm_i_mark_inaccessible_guardeds ();
+
+ /* This marking might have changed the situation for weak vectors
+ and might have turned up new guardians that need to be processed,
+ so we do it all over again.
+ */
+ if (again)
+ continue;
+
+ /* Nothing new marked in this round, we are done.
+ */
+ break;
+ }
+
+ //fprintf (stderr, "%d loops\n", loops);
- /* FIXME: we should have a means to register C functions to be run
- * in different phases of GC
+ /* Remove all unmarked entries from the weak vectors.
*/
- scm_mark_subr_table ();
+ scm_i_remove_weaks_from_weak_vectors ();
+
+ /* Bring hashtables upto date.
+ */
+ scm_i_scan_weak_hashtables ();
}
/* {Mark/Sweep}
@@ -144,6 +191,7 @@ Perhaps this would work better with an explicit markstack?
*/
+
void
scm_gc_mark_dependencies (SCM p)
#define FUNC_NAME "scm_gc_mark_dependencies"
@@ -267,62 +315,7 @@ scm_gc_mark_dependencies (SCM p)
break;
case scm_tc7_wvect:
- SCM_I_SET_WVECT_GC_CHAIN (ptr, scm_weak_vectors);
- scm_weak_vectors = ptr;
- if (SCM_IS_WHVEC_ANY (ptr))
- {
- long x;
- long len;
- int weak_keys;
- int weak_values;
-
- len = SCM_SIMPLE_VECTOR_LENGTH (ptr);
- weak_keys = SCM_WVECT_WEAK_KEY_P (ptr);
- weak_values = SCM_WVECT_WEAK_VALUE_P (ptr);
-
- for (x = 0; x < len; ++x)
- {
- SCM alist;
- alist = SCM_SIMPLE_VECTOR_REF (ptr, x);
-
- /* mark everything on the alist except the keys or
- * values, according to weak_values and weak_keys. */
- while ( scm_is_pair (alist)
- && !SCM_GC_MARK_P (alist)
- && scm_is_pair (SCM_CAR (alist)))
- {
- SCM kvpair;
- SCM next_alist;
-
- kvpair = SCM_CAR (alist);
- next_alist = SCM_CDR (alist);
- /*
- * Do not do this:
- * SCM_SET_GC_MARK (alist);
- * SCM_SET_GC_MARK (kvpair);
- *
- * It may be that either the key or value is protected by
- * an escaped reference to part of the spine of this alist.
- * If we mark the spine here, and only mark one or neither of the
- * key and value, they may never be properly marked.
- * This leads to a horrible situation in which an alist containing
- * freelist cells is exported.
- *
- * So only mark the spines of these arrays last of all marking.
- * If somebody confuses us by constructing a weak vector
- * with a circular alist then we are hosed, but at least we
- * won't prematurely drop table entries.
- */
- if (!weak_keys)
- scm_gc_mark (SCM_CAR (kvpair));
- if (!weak_values)
- scm_gc_mark (SCM_CDR (kvpair));
- alist = next_alist;
- }
- if (SCM_NIMP (alist))
- scm_gc_mark (alist);
- }
- }
+ scm_i_mark_weak_vector (ptr);
break;
case scm_tc7_symbol:
@@ -389,8 +382,8 @@ scm_gc_mark_dependencies (SCM p)
were called with.)
*/
return ;
-
-gc_mark_loop:
+
+ gc_mark_loop:
if (SCM_IMP (ptr))
return;