Karim Belabas on Thu, 17 Sep 2009 14:15:44 +0200 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
Re: Static analyzer run |
* Lorenz Minder [2009-09-14 10:07]: > I've run PARI through a static source code analyzer to see if it finds > any bugs (and to see if the tool is worth anything). [...] > * Flx_resultant(): variables still in use were garbage collected. > (In the old code, try replacing "if(++cnt == 100)" by "if(++cnt == 1)" > to see those problems.) diff --git a/src/basemath/Flx.c b/src/basemath/Flx.c --- a/src/basemath/Flx.c +++ b/src/basemath/Flx.c @@ -1280,7 +1280,7 @@ if (both_odd(da,db)) res = p - res; if (lb != 1) res = Fl_mul(res, Fl_powu(lb, da - dc, p), p); - if (++cnt == 100) { cnt = 0; c = gerepileuptoleaf(av, c); } + if (++cnt == 100) { cnt = 0; gerepileall(av, 2, &a, &b); } da = db; /* = degpol(a) */ db = dc; /* = degpol(b) */ } diff --git a/src/basemath/base1.c b/src/basemath/ A note on this one: the old code was actually "not completely incorrect" since a,b are non-recursive objects of bounded size, a priori less than 100 times the stack space used up in a the 2 loop iterations during which they must survive. A simple avma = av would have been fine (and better). This technique of using for a very limited time an object that has just been reclaimed by the garbage collector is not infrequent in our code, and mandatorily flagged with a /* HACK */ comment. It saves a little time by avoiding an actual gerepile. The code becomes completely wrong if you replace 100 by a much smaller number of course. Or if the Flx_rem implementation is replaced by something needing much more stack space (Newton + FTT, say). So I agree that in this case, the code should be fixed. The true culprit is of course the stack/gerepile model here. We'd much rather have the successive Flx_rem() store their result in pre-allocated storage (whose size is easy to estimate; only the 2 last results need to be kept), instead of endlessly adding to the stack then reclaiming garbage in either hackish or inefficient way. It's actually very simple to implement such an Flx_remz(a, b, z) function (stores Flx_rem(a, b) in pre-allocated z), because in the case where this would be difficult (Newton), the current code already calls a gerepile, which could be replaced by a copy at not coѕe. >> TODO :-). Cheers, K.B. -- Karim Belabas, IMB (UMR 5251) Tel: (+33) (0)5 40 00 26 17 Universite Bordeaux 1 Fax: (+33) (0)5 40 00 69 50 351, cours de la Liberation http://www.math.u-bordeaux1.fr/~belabas/ F-33405 Talence (France) http://pari.math.u-bordeaux1.fr/ [PARI/GP] `