mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-17 01:00:20 +02:00
Allocate data for structures on an eight-byte boundary, as
required by the tagging system. * struct.c (alloc_struct): New function. (scm_make_struct, scm_make_vtable_vtable): Call it. * struct.h (scm_struct_n_extra_words): Bump to 3. (scm_struct_i_ptr): New "field". * gc.c (scm_gc_sweep): When we need to free the data, use the information stored by alloc_struct to find the beginning of the block allocated to the structure, so we can free it.
This commit is contained in:
parent
2dfc85c018
commit
14d1400fa7
3 changed files with 74 additions and 29 deletions
|
@ -516,7 +516,9 @@ gc_mark_nimp:
|
||||||
layout = vtable_data[scm_struct_i_layout];
|
layout = vtable_data[scm_struct_i_layout];
|
||||||
len = SCM_LENGTH (layout);
|
len = SCM_LENGTH (layout);
|
||||||
fields_desc = SCM_CHARS (layout);
|
fields_desc = SCM_CHARS (layout);
|
||||||
mem = (SCM *)SCM_GCCDR (ptr); /* like struct_data but removes mark */
|
/* We're using SCM_GCCDR here like STRUCT_DATA, except
|
||||||
|
that it removes the mark */
|
||||||
|
mem = (SCM *)SCM_GCCDR (ptr);
|
||||||
|
|
||||||
if (len)
|
if (len)
|
||||||
{
|
{
|
||||||
|
@ -959,12 +961,10 @@ scm_gc_sweep ()
|
||||||
|
|
||||||
if ((SCM_CDR (vcell) == 0) || (SCM_CDR (vcell) == 1))
|
if ((SCM_CDR (vcell) == 0) || (SCM_CDR (vcell) == 1))
|
||||||
{
|
{
|
||||||
SCM * mem;
|
SCM *p = (SCM *) SCM_GCCDR (scmptr);
|
||||||
SCM amt;
|
m += p[scm_struct_i_n_words] * sizeof (SCM);
|
||||||
mem = (SCM *)SCM_CDR (scmptr);
|
/* I feel like I'm programming in BCPL here... */
|
||||||
amt = mem[- scm_struct_n_extra_words];
|
free ((char *) p[scm_struct_i_ptr]);
|
||||||
free (mem - scm_struct_n_extra_words);
|
|
||||||
m += amt * sizeof (SCM);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -276,6 +276,65 @@ scm_struct_vtable_p (x)
|
||||||
: SCM_BOOL_F);
|
: SCM_BOOL_F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* All struct data must be allocated at an address whose bottom three
|
||||||
|
bits are zero. This is because the tag for a struct lives in the
|
||||||
|
bottom three bits of the struct's car, and the upper bits point to
|
||||||
|
the data of its vtable, which is a struct itself. Thus, if the
|
||||||
|
address of that data doesn't end in three zeros, tagging it will
|
||||||
|
destroy the pointer.
|
||||||
|
|
||||||
|
This function allocates a block of memory, and returns a pointer at
|
||||||
|
least scm_struct_n_extra_words words into the block. Furthermore,
|
||||||
|
it guarantees that that pointer's least three significant bits are
|
||||||
|
all zero.
|
||||||
|
|
||||||
|
The argument n_words should be the number of words that should
|
||||||
|
appear after the returned address. (That is, it shouldn't include
|
||||||
|
scm_struct_n_extra_words.)
|
||||||
|
|
||||||
|
This function initializes the following fields of the struct:
|
||||||
|
|
||||||
|
scm_struct_i_ptr --- the actual stort of the block of memory; the
|
||||||
|
address you should pass to 'free' to dispose of the block.
|
||||||
|
This field allows us to both guarantee that the returned
|
||||||
|
address is divisible by eight, and allow the GC to free the
|
||||||
|
block.
|
||||||
|
|
||||||
|
scm_struct_i_n_words --- the number of words allocated to the
|
||||||
|
block, including the extra fields. This is used by the GC.
|
||||||
|
|
||||||
|
scm_struct_i_tag --- a unique tag assigned to this struct,
|
||||||
|
allocated according to struct_num.
|
||||||
|
|
||||||
|
Ugh. */
|
||||||
|
|
||||||
|
|
||||||
|
static SCM *alloc_struct SCM_P ((int n_words, char *who));
|
||||||
|
|
||||||
|
static SCM *
|
||||||
|
alloc_struct (n_words, who)
|
||||||
|
int n_words;
|
||||||
|
char *who;
|
||||||
|
{
|
||||||
|
int size = sizeof (SCM) * (n_words + scm_struct_n_extra_words) + 7;
|
||||||
|
SCM *block = (SCM *) scm_must_malloc (size, who);
|
||||||
|
|
||||||
|
/* Adjust the pointer to hide the extra words. */
|
||||||
|
SCM *p = block + scm_struct_n_extra_words;
|
||||||
|
|
||||||
|
/* Adjust it even further so it's aligned on an eight-byte boundary. */
|
||||||
|
p = (SCM *) (((SCM) p + 7) & ~7);
|
||||||
|
|
||||||
|
/* Initialize a few fields as described above. */
|
||||||
|
p[scm_struct_i_ptr] = (SCM) block;
|
||||||
|
p[scm_struct_i_n_words] = (SCM) (scm_struct_n_extra_words + n_words);
|
||||||
|
p[scm_struct_i_tag] = struct_num++;
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SCM_PROC (s_make_struct, "make-struct", 2, 0, 1, scm_make_struct);
|
SCM_PROC (s_make_struct, "make-struct", 2, 0, 1, scm_make_struct);
|
||||||
|
|
||||||
SCM
|
SCM
|
||||||
|
@ -292,22 +351,15 @@ scm_make_struct (vtable, tail_array_size, init)
|
||||||
|
|
||||||
SCM_ASSERT ((SCM_BOOL_F != scm_struct_vtable_p (vtable)),
|
SCM_ASSERT ((SCM_BOOL_F != scm_struct_vtable_p (vtable)),
|
||||||
vtable, SCM_ARG1, s_make_struct);
|
vtable, SCM_ARG1, s_make_struct);
|
||||||
SCM_ASSERT (SCM_INUMP (tail_array_size), tail_array_size, SCM_ARG2, s_make_struct);
|
SCM_ASSERT (SCM_INUMP (tail_array_size), tail_array_size, SCM_ARG2,
|
||||||
|
s_make_struct);
|
||||||
|
|
||||||
layout = SCM_STRUCT_DATA (vtable)[scm_struct_i_layout];
|
layout = SCM_STRUCT_DATA (vtable)[scm_struct_i_layout];
|
||||||
basic_size = SCM_LENGTH (layout) / 2;
|
basic_size = SCM_LENGTH (layout) / 2;
|
||||||
tail_elts = SCM_INUM (tail_array_size);
|
tail_elts = SCM_INUM (tail_array_size);
|
||||||
SCM_NEWCELL (handle);
|
SCM_NEWCELL (handle);
|
||||||
SCM_DEFER_INTS;
|
SCM_DEFER_INTS;
|
||||||
data = (SCM*)scm_must_malloc (sizeof (SCM) * (scm_struct_n_extra_words
|
data = alloc_struct (basic_size + tail_elts, "make-struct");
|
||||||
+ basic_size
|
|
||||||
+ tail_elts),
|
|
||||||
"structure");
|
|
||||||
data += scm_struct_n_extra_words;
|
|
||||||
data[scm_struct_i_n_words] = (SCM) (scm_struct_n_extra_words
|
|
||||||
+ basic_size
|
|
||||||
+ tail_elts);
|
|
||||||
data[scm_struct_i_tag] = struct_num++;
|
|
||||||
SCM_SETCDR (handle, data);
|
SCM_SETCDR (handle, data);
|
||||||
SCM_SETCAR (handle, ((SCM)SCM_STRUCT_DATA (vtable)) + scm_tc3_cons_gloc);
|
SCM_SETCAR (handle, ((SCM)SCM_STRUCT_DATA (vtable)) + scm_tc3_cons_gloc);
|
||||||
init_struct (handle, tail_elts, init);
|
init_struct (handle, tail_elts, init);
|
||||||
|
@ -334,8 +386,8 @@ scm_make_vtable_vtable (extra_fields, tail_array_size, init)
|
||||||
|
|
||||||
SCM_ASSERT (SCM_NIMP (extra_fields) && SCM_ROSTRINGP (extra_fields),
|
SCM_ASSERT (SCM_NIMP (extra_fields) && SCM_ROSTRINGP (extra_fields),
|
||||||
extra_fields, SCM_ARG1, s_make_vtable_vtable);
|
extra_fields, SCM_ARG1, s_make_vtable_vtable);
|
||||||
SCM_ASSERT (SCM_INUMP (tail_array_size), tail_array_size, SCM_ARG3, s_make_vtable_vtable);
|
SCM_ASSERT (SCM_INUMP (tail_array_size), tail_array_size, SCM_ARG2,
|
||||||
|
s_make_vtable_vtable);
|
||||||
|
|
||||||
fields = scm_string_append (scm_listify (required_vtable_fields,
|
fields = scm_string_append (scm_listify (required_vtable_fields,
|
||||||
extra_fields,
|
extra_fields,
|
||||||
|
@ -345,15 +397,7 @@ scm_make_vtable_vtable (extra_fields, tail_array_size, init)
|
||||||
tail_elts = SCM_INUM (tail_array_size);
|
tail_elts = SCM_INUM (tail_array_size);
|
||||||
SCM_NEWCELL (handle);
|
SCM_NEWCELL (handle);
|
||||||
SCM_DEFER_INTS;
|
SCM_DEFER_INTS;
|
||||||
data = (SCM *) scm_must_malloc (sizeof (SCM) * (scm_struct_n_extra_words
|
data = alloc_struct (basic_size + tail_elts, "make-vtable-vtable");
|
||||||
+ basic_size
|
|
||||||
+ tail_elts),
|
|
||||||
"structure");
|
|
||||||
data += scm_struct_n_extra_words;
|
|
||||||
data[scm_struct_i_n_words] = (SCM) (scm_struct_n_extra_words
|
|
||||||
+ basic_size
|
|
||||||
+ tail_elts);
|
|
||||||
data[scm_struct_i_tag] = struct_num++;
|
|
||||||
SCM_SETCDR (handle, data);
|
SCM_SETCDR (handle, data);
|
||||||
SCM_SETCAR (handle, ((SCM)data) + scm_tc3_cons_gloc);
|
SCM_SETCAR (handle, ((SCM)data) + scm_tc3_cons_gloc);
|
||||||
SCM_STRUCT_LAYOUT (handle) = layout;
|
SCM_STRUCT_LAYOUT (handle) = layout;
|
||||||
|
|
|
@ -49,9 +49,10 @@
|
||||||
|
|
||||||
|
|
||||||
/* Number of words with negative index */
|
/* Number of words with negative index */
|
||||||
#define scm_struct_n_extra_words 2
|
#define scm_struct_n_extra_words 3
|
||||||
|
|
||||||
/* These are how the initial words of a vtable are allocated. */
|
/* These are how the initial words of a vtable are allocated. */
|
||||||
|
#define scm_struct_i_ptr -3 /* start of block (see alloc_struct) */
|
||||||
#define scm_struct_i_n_words -2 /* How many words allocated to this struct? */
|
#define scm_struct_i_n_words -2 /* How many words allocated to this struct? */
|
||||||
#define scm_struct_i_tag -1 /* A unique tag for this type.. */
|
#define scm_struct_i_tag -1 /* A unique tag for this type.. */
|
||||||
#define scm_struct_i_layout 0 /* A symbol describing the physical arrangement of this type. */
|
#define scm_struct_i_layout 0 /* A symbol describing the physical arrangement of this type. */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue