mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-12 06:41:13 +02:00
* hashtab.c (scm_i_rehash): Cope with the case that a GC modifies
the hashtable. (scm_hash_fn_create_handle_x): Likewise. * vectors.h (SCM_I_SET_WVECT_TYPE): New, for use in scm_i_rehash.
This commit is contained in:
parent
57491e856d
commit
bc6580eb22
2 changed files with 32 additions and 13 deletions
|
@ -162,25 +162,40 @@ scm_i_rehash (SCM table,
|
||||||
else
|
else
|
||||||
new_buckets = scm_c_make_vector (new_size, SCM_EOL);
|
new_buckets = scm_c_make_vector (new_size, SCM_EOL);
|
||||||
|
|
||||||
|
/* When this is a weak hashtable, running the GC might change it.
|
||||||
|
We need to cope with this while rehashing its elements. We do
|
||||||
|
this by first installing the new, empty bucket vector and turning
|
||||||
|
the old bucket vector into a regularily scanned weak vector.
|
||||||
|
Then we iterate over the elements in the old bucket vector.
|
||||||
|
While iterating, the elements in LS will not disappear since they
|
||||||
|
are protected.
|
||||||
|
*/
|
||||||
|
|
||||||
|
SCM_SET_HASHTABLE_VECTOR (table, new_buckets);
|
||||||
|
SCM_SET_HASHTABLE_N_ITEMS (table, 0);
|
||||||
|
if (SCM_HASHTABLE_WEAK_P (table))
|
||||||
|
SCM_I_SET_WVECT_TYPE (buckets, (SCM_HASHTABLE_FLAGS (table)));
|
||||||
|
|
||||||
old_size = SCM_SIMPLE_VECTOR_LENGTH (buckets);
|
old_size = SCM_SIMPLE_VECTOR_LENGTH (buckets);
|
||||||
for (i = 0; i < old_size; ++i)
|
for (i = 0; i < old_size; ++i)
|
||||||
{
|
{
|
||||||
SCM ls = SCM_SIMPLE_VECTOR_REF (buckets, i), handle;
|
SCM ls, cell, handle;
|
||||||
while (!scm_is_null (ls))
|
|
||||||
|
ls = SCM_SIMPLE_VECTOR_REF (buckets, i);
|
||||||
|
while (scm_is_pair (ls))
|
||||||
{
|
{
|
||||||
unsigned long h;
|
unsigned long h;
|
||||||
handle = SCM_CAR (ls);
|
cell = ls;
|
||||||
|
handle = SCM_CAR (cell);
|
||||||
|
ls = SCM_CDR (ls);
|
||||||
h = hash_fn (SCM_CAR (handle), new_size, closure);
|
h = hash_fn (SCM_CAR (handle), new_size, closure);
|
||||||
if (h >= new_size)
|
if (h >= new_size)
|
||||||
scm_out_of_range (func_name, scm_from_ulong (h));
|
scm_out_of_range (func_name, scm_from_ulong (h));
|
||||||
SCM_SIMPLE_VECTOR_SET
|
SCM_SETCDR (cell, SCM_SIMPLE_VECTOR_REF (new_buckets, h));
|
||||||
(new_buckets, h,
|
SCM_SIMPLE_VECTOR_SET (new_buckets, h, cell);
|
||||||
scm_cons (handle,
|
SCM_HASHTABLE_INCREMENT (table);
|
||||||
SCM_SIMPLE_VECTOR_REF (new_buckets, h)));
|
|
||||||
ls = SCM_CDR (ls);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SCM_SET_HASHTABLE_VECTOR (table, new_buckets);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -475,8 +490,11 @@ scm_hash_fn_create_handle_x (SCM table, SCM obj, SCM init, unsigned long (*hash_
|
||||||
return it;
|
return it;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SCM old_bucket = SCM_SIMPLE_VECTOR_REF (buckets, k);
|
/* We need to take care not to run the GC while linking the new
|
||||||
SCM new_bucket = scm_acons (obj, init, old_bucket);
|
bucket into its chain. A GC might change a weak hashtable.
|
||||||
|
*/
|
||||||
|
SCM new_bucket = scm_acons (obj, init, SCM_EOL);
|
||||||
|
SCM_SETCDR (new_bucket, SCM_SIMPLE_VECTOR_REF (buckets, k));
|
||||||
SCM_SIMPLE_VECTOR_SET (buckets, k, new_bucket);
|
SCM_SIMPLE_VECTOR_SET (buckets, k, new_bucket);
|
||||||
if (table != buckets)
|
if (table != buckets)
|
||||||
{
|
{
|
||||||
|
|
|
@ -95,8 +95,9 @@ SCM_API SCM scm_i_vector_equal_p (SCM x, SCM y);
|
||||||
#define SCM_I_WVECT_VELTS SCM_I_VECTOR_ELTS
|
#define SCM_I_WVECT_VELTS SCM_I_VECTOR_ELTS
|
||||||
#define SCM_I_WVECT_GC_WVELTS SCM_I_VECTOR_WELTS
|
#define SCM_I_WVECT_GC_WVELTS SCM_I_VECTOR_WELTS
|
||||||
#define SCM_I_WVECT_TYPE(x) (SCM_CELL_WORD_2 (x))
|
#define SCM_I_WVECT_TYPE(x) (SCM_CELL_WORD_2 (x))
|
||||||
#define SCM_I_WVECT_GC_CHAIN(X) (SCM_CELL_OBJECT_3 (X))
|
#define SCM_I_SET_WVECT_TYPE(x, t) (SCM_SET_CELL_WORD_2 ((x),(t)))
|
||||||
#define SCM_I_SET_WVECT_GC_CHAIN(X, o) (SCM_SET_CELL_OBJECT_3 ((X), (o)))
|
#define SCM_I_WVECT_GC_CHAIN(x) (SCM_CELL_OBJECT_3 (x))
|
||||||
|
#define SCM_I_SET_WVECT_GC_CHAIN(x, o) (SCM_SET_CELL_OBJECT_3 ((x), (o)))
|
||||||
|
|
||||||
SCM_API SCM scm_i_allocate_weak_vector (scm_t_bits type, SCM size, SCM fill);
|
SCM_API SCM scm_i_allocate_weak_vector (scm_t_bits type, SCM size, SCM fill);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue