This is the mail archive of the
guile@sourceware.cygnus.com
mailing list for the Guile project.
Re: I suspect a serious bug: it is in the GC
- To: Bernard URBAN <Bernard dot Urban at meteo dot fr>
- Subject: Re: I suspect a serious bug: it is in the GC
- From: Greg Harvey <Greg dot Harvey at thezone dot net>
- Date: 05 Oct 1999 19:12:27 -0230
- Cc: guile at sourceware dot cygnus dot com, jimb at red-bean dot com
- References: <9910041706.AA22537@min.meteo.fr>
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