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]

Re: New Garbage Collection for Smobs


> 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