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