1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-07-05 17:20:18 +02:00

* gc.c (scm_gc_mark, scm_gc_sweep): Remove vcell = 1 magic.

(scm_structs_to_free): New variable.
(scm_gc_sweep): Hook up structs to free on the scm_structs_to_free
chain.
This commit is contained in:
Mikael Djurfeldt 2000-08-09 18:29:10 +00:00
parent 163fada3d3
commit 7445e0e8eb

View file

@ -319,6 +319,10 @@ int scm_block_gc = 1;
*/ */
SCM scm_weak_vectors; SCM scm_weak_vectors;
/* During collection, this accumulates structures which are to be freed.
*/
SCM scm_structs_to_free;
/* GC Statistics Keeping /* GC Statistics Keeping
*/ */
unsigned long scm_cells_allocated = 0; unsigned long scm_cells_allocated = 0;
@ -1038,55 +1042,48 @@ gc_mark_nimp:
*/ */
scm_bits_t word0 = SCM_CELL_WORD_0 (ptr) - scm_tc3_cons_gloc; scm_bits_t word0 = SCM_CELL_WORD_0 (ptr) - scm_tc3_cons_gloc;
scm_bits_t * vtable_data = (scm_bits_t *) word0; /* access as struct */ scm_bits_t * vtable_data = (scm_bits_t *) word0; /* access as struct */
switch (vtable_data [scm_vtable_index_vcell]) if (vtable_data [scm_vtable_index_vcell] != 0)
{ {
default: /* ptr is a gloc */
{ SCM gloc_car = SCM_PACK (word0);
/* ptr is a gloc */ scm_gc_mark (gloc_car);
SCM gloc_car = SCM_PACK (word0); ptr = SCM_GCCDR (ptr);
scm_gc_mark (gloc_car); goto gc_mark_loop;
ptr = SCM_GCCDR (ptr); }
goto gc_mark_loop; else
} {
case 1: /* ! */ /* ptr is a struct */
case 0: /* ! */ SCM layout = SCM_PACK (vtable_data [scm_vtable_index_layout]);
{ int len = SCM_LENGTH (layout);
/* ptr is a struct */ char * fields_desc = SCM_CHARS (layout);
SCM layout = SCM_PACK (vtable_data [scm_vtable_index_layout]); /* We're using SCM_GCCDR here like STRUCT_DATA, except
int len = SCM_LENGTH (layout); that it removes the mark */
char * fields_desc = SCM_CHARS (layout); scm_bits_t * struct_data = (scm_bits_t *) SCM_UNPACK (SCM_GCCDR (ptr));
/* We're using SCM_GCCDR here like STRUCT_DATA, except
that it removes the mark */
scm_bits_t * struct_data = (scm_bits_t *) SCM_UNPACK (SCM_GCCDR (ptr));
if (vtable_data[scm_struct_i_flags] & SCM_STRUCTF_ENTITY) if (vtable_data[scm_struct_i_flags] & SCM_STRUCTF_ENTITY)
{ {
scm_gc_mark (SCM_PACK (struct_data[scm_struct_i_procedure])); scm_gc_mark (SCM_PACK (struct_data[scm_struct_i_procedure]));
scm_gc_mark (SCM_PACK (struct_data[scm_struct_i_setter])); scm_gc_mark (SCM_PACK (struct_data[scm_struct_i_setter]));
} }
if (len) if (len)
{ {
int x; int x;
for (x = 0; x < len - 2; x += 2, ++struct_data) for (x = 0; x < len - 2; x += 2, ++struct_data)
if (fields_desc[x] == 'p')
scm_gc_mark (SCM_PACK (*struct_data));
if (fields_desc[x] == 'p') if (fields_desc[x] == 'p')
{ scm_gc_mark (SCM_PACK (*struct_data));
if (SCM_LAYOUT_TAILP (fields_desc[x + 1])) if (fields_desc[x] == 'p')
for (x = *struct_data; x; --x) {
scm_gc_mark (SCM_PACK (*++struct_data)); if (SCM_LAYOUT_TAILP (fields_desc[x + 1]))
else for (x = *struct_data; x; --x)
scm_gc_mark (SCM_PACK (*struct_data)); scm_gc_mark (SCM_PACK (*++struct_data));
} else
} scm_gc_mark (SCM_PACK (*struct_data));
if (vtable_data [scm_vtable_index_vcell] == 0) }
{ }
vtable_data [scm_vtable_index_vcell] = 1; /* mark vtable */
ptr = SCM_PACK (vtable_data [scm_vtable_index_vtable]); ptr = SCM_PACK (vtable_data [scm_vtable_index_vtable]);
goto gc_mark_loop; goto gc_mark_loop;
}
}
} }
} }
break; break;
@ -1467,24 +1464,22 @@ scm_gc_sweep ()
* struct or a gloc. See the corresponding comment in * struct or a gloc. See the corresponding comment in
* scm_gc_mark. * scm_gc_mark.
*/ */
scm_bits_t word0 = SCM_CELL_WORD_0 (scmptr) - scm_tc3_cons_gloc; scm_bits_t word0 = (SCM_CELL_WORD_0 (scmptr)
scm_bits_t * vtable_data = (scm_bits_t *) word0; /* access as struct */ - scm_tc3_cons_gloc);
/* access as struct */
scm_bits_t * vtable_data = (scm_bits_t *) word0;
if (SCM_GCMARKP (scmptr)) if (SCM_GCMARKP (scmptr))
goto cmrkcontinue;
else if (vtable_data[scm_vtable_index_vcell] == 0)
{ {
if (vtable_data [scm_vtable_index_vcell] == 1) /* Structs need to be freed in a special order.
vtable_data [scm_vtable_index_vcell] = 0; * This is handled by GC C hooks in struct.c.
*/
SCM_SET_STRUCT_GC_CHAIN (scmptr, scm_structs_to_free);
scm_structs_to_free = scmptr;
goto cmrkcontinue; goto cmrkcontinue;
} }
else /* fall through so that scmptr gets collected */
{
if (vtable_data [scm_vtable_index_vcell] == 0
|| vtable_data [scm_vtable_index_vcell] == 1)
{
scm_struct_free_t free_struct_data
= (scm_struct_free_t) vtable_data[scm_struct_i_free];
m += free_struct_data (vtable_data, (scm_bits_t *) SCM_UNPACK (SCM_GCCDR (scmptr)));
}
}
} }
break; break;
case scm_tcs_cons_imcar: case scm_tcs_cons_imcar: