This is the mail archive of the guile@sourceware.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: I suspect a serious bug: it is in the GC


Bernard URBAN <Bernard.Urban@meteo.fr> writes:

[snip demonstration]
> It is probably uncommon to allocate a huge vector of double as in
> the above exemple, so it may explain why this was not discovered
> before. 
> 
> I have then put some printf in some routines of gc.c to analyse
> what happens.
> 
> The allocation happen in 2 steps: first, a vector with unbound content
> is allocated. If this triggers a GC, it is safe.
> Then, all the N elements of the vector must be initialized. 
> This calls NEWCELL N times.
> If this operation triggers GC at step N1, it leads to the above problem, by
> apparently deallocating some of the cells allocated before step N1.
>
> If someone has more hints...

Ok, here's what's happening. First, gh_doubles2scm is allocating a big
vector. No problem here, but this vector is not a scheme object, it's
just a c vector as far as guile's concerned, so each of the newly
created doubles being put into it are not reachable by any means until
the end of the function, when makvect (which just constructs a real
vector from it) is called with the contents, so if a garbage
collection is caused by scm_makdbl all of the previously allocated
doubles will be collected. I've attached a patch.


1999-10-05  Greg Harvey  <Greg.Harvey@thezone.net>

	* gh_data.c (gh_doubles2scm): create a scm_tc7_dvect, rather than
	a normal vector containing doubles. Also solves the problem of
	large calls causing some doubles to be collected.
	(gh_ints2scm): make sure the vector (and early elements) can be
	found by the gc.

Index: gh_data.c
===================================================================
RCS file: /cvs/guile/guile/guile-core/libguile/gh_data.c,v
retrieving revision 1.20
diff -c -c -r1.20 gh_data.c
*** gh_data.c	1999/08/30 07:02:25	1.20
--- gh_data.c	1999/10/05 21:40:51
***************
*** 141,165 ****
  SCM
  gh_ints2scm (int *d, int n)
  {
!   SCM *m;
    int i;
!   m = (SCM*) scm_must_malloc (n * sizeof (SCM), "vector");
    for (i = 0; i < n; ++i)
!     m[i] = (d[i] >= SCM_MOST_NEGATIVE_FIXNUM
! 	    && d[i] <= SCM_MOST_POSITIVE_FIXNUM
! 	    ? SCM_MAKINUM (d[i])
! 	    : scm_long2big (d[i]));
!   return makvect ((char *) m, n, scm_tc7_vector);
  }
  
  SCM
  gh_doubles2scm (double *d, int n)
  {
!   SCM *m = (SCM*) scm_must_malloc (n * sizeof (SCM), "vector");
!   int i;
!   for (i = 0; i < n; ++i)
!     m[i] = scm_makdbl (d[i], 0.0);
!   return makvect ((char *) m, n, scm_tc7_vector);
  }
  
  SCM
--- 141,163 ----
  SCM
  gh_ints2scm (int *d, int n)
  {
!   SCM v;
    int i;
!   v = scm_make_vector(SCM_MAKINUM(n), SCM_UNSPECIFIED);
    for (i = 0; i < n; ++i)
!     SCM_VELTS(v)[i] = (d[i] >= SCM_MOST_NEGATIVE_FIXNUM
!                        && d[i] <= SCM_MOST_POSITIVE_FIXNUM
!                        ? SCM_MAKINUM (d[i])
!                        : scm_long2big (d[i]));
!   return v;
  }
  
  SCM
  gh_doubles2scm (double *d, int n)
  {
!   char *m = scm_must_malloc(n * sizeof (double), "vector");
!   memcpy(m, d, n*sizeof(double));
!   return makvect(m, n, scm_tc7_dvect);
  }
  
  SCM

-- 
Greg

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]