This is the mail archive of the guile@cygnus.com mailing list for the guile project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
> Your table is your new smob type, yes?
yes
> It keeps several lists of strings,
> and these lists and strings are ordinary Scheme lists and strings?
Yes, the table keeps SCM types with arbitrary data.
When they are lists of strings then I get crashes <helpless shrug>
when they are other things then I don't.
> Could you post your marker function?
typedef struct triple_S triple_T;
struct triple_S
{
unsigned long ID;
SCM attribute;
SCM value;
};
typedef struct e_triple_S e_triple_T;
struct e_triple_S
{
triple_T t;
index_block_T *b;
};
typedef struct index_block_S index_block_T;
struct index_block_S
{
unsigned short usedspace;
unsigned char is_baselevel;
unsigned char comparison_ID;
union
{
triple_T base[ BASE_BLOCKSIZE ];
e_triple_T non_base[ NON_BASE_BLOCKSIZE ];
} block;
};
static void index_block_mark( index_block_T *b )
{
if( 0 == b ) return;
if( b->is_baselevel )
{
triple_T *t = b->block.base;
triple_T *final = t + b->usedspace;
for( ; t < final; t++ )
{
scm_gc_mark( t->attribute );
scm_gc_mark( t->value ); <-- CRASH HERE
}
}
else
{
e_triple_T *e = b->block.non_base;
e_triple_T *final = e + b->usedspace;
index_block_mark( e->b );
/* b->block.non_base[0].t is not used and unitialised */
for( ; (++e) < final; )
{
scm_gc_mark( e->t.attribute );
scm_gc_mark( e->t.value );
index_block_mark( e->b );
}
}
}
static SCM table_mark( SCM x ) <--- SMOB MARK ENTER HERE
{
table_T *T = table_S2I( x );
if( T )
{
index_block_mark( T->primary.root );
index_block_mark( T->secondary.root );
SCM_SETGC8MARK( x );
}
return( SCM_BOOL_F );
}
> the instructions in the data-rep essay should work for all Guile types.
I skimmed through it the first time, I'll have a closer second look.
> The essay talks about that gotcha. There should be a note about this
> in the Typechecking section, too...
>
> Note that, since a smob's mark bit lives in its CAR, along with the
> smob's type tag, the technique for checking the type of a smob
> described in section Typechecking will not necessarily work during
> GC. If you need to find out whether a given object is a particular
> smob type during GC, use the following macro:
>
> Macro: void SCM_GCTYP16 (SCM x)
> Return the type bits of the smob x, with the mark bit clear.
>
> Use this macro instead of SCM_CAR to check the type of a smob
> during GC. Usually, only code called by the smob's mark function
> need worry about this.
>
> It is usually a good idea to minimize the amount of processing done
> during garbage collection; keep mark and free functions very
> simple. Since collections occur at unpredictable times, it is easy for
> any unusual activity to interfere with normal code.
It would be nice to have a typecheck method that works anytime regardless of
wherever it is called from. My routine for converting SCM to pointer does
a typecheck first (seems fair) and returns 0 if the type is wrong.
Whenever I convert to a pointer I use this routine. Why should I do something
different in the garbage collection routines?
As you said, garbage collection routines are hard to debug,
why make them hard to write too?
- Tel