gcl-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gcl-devel] Uninitialized stack gaps and conservative garbage collection


From: Camm Maguire
Subject: [Gcl-devel] Uninitialized stack gaps and conservative garbage collection
Date: Tue, 24 May 2005 17:40:46 -0400
User-agent: SEMI/1.14.3 (Ushinoya) FLIM/1.14.3 (Unebigory ōmae) APEL/10.3 Emacs/21.2 (i386-debian-linux-gnu) MULE/5.0 (SAKAKI)

Greetings!  GCL is a lisp system that compiles to native object code
via the intermediary of gcc.  It uses a conservative garbage
collection algorithm, which means that it walks the C stack to find
likely objects in use by automatic variables, and holds on to these.
This works quite well in practice.

For very large systems, the likelihood of holding onto objects which
should be collected increases.  In looking into this, it has come to
my attention that regardless of how carefully the C programmer
initializes variables on the stack, gcc will quite commonly allocate
extra space inaccessbile via any C variable.  These 'stack gaps' can
wind up permanently preventing a large portion of user memory from
ever being collected with this algorithm.

Ideally, I'd like to be able to have each C function carefully
initialize a contiguous stack to minimize or eliminate this problem.
Even better would be a gcc switch which would simply zero out each
stack frame at the beginning of each function, though this could be
expensive in terms of performance.  Advice is most appreciated.  I'd
most like the solution to be portable.  I know about
-mpreferred-stack-boundary, but I am unsure if its absense on other
architectures means there is no stack padding there anyway.

Here is my ridiculous kludge which nevertheless works at least here:

void wipe_stack(VOL void *) __attribute__ ((noinline));
void
wipe_stack(VOL void *l) {

#if CSTACK_DIRECTION == -1
   if (l>(void *)&l) bzero((void *)&l,l-(void *)&l);
#else
  l+=sizeof(l);
  if ((void *)&l>l) bzero(l,(void *)&l-l);
#endif

}

object fLfuncall(object fun,...) { 

  va_list ap;
  object *new;
  int i,n = VFUN_NARGS-1;

  if (n>=65) FEerror("arg limit exceeded",0);
  new=ZALLOCA(n*sizeof(*new));

  /* There are 3 unused words on top of esp before and after the
  alloca, as well as extra esp allocation in the alloca itself, even
  though the alloca call is padded to 16 bytes.  So let's wipe the
  crud from the stack... */

  wipe_stack(&n);
  ...

}

Take care,

-- 
Camm Maguire                                            address@hidden
==========================================================================
"The earth is but one country, and mankind its citizens."  --  Baha'u'llah




reply via email to

[Prev in Thread] Current Thread [Next in Thread]