Gerhard Niklasch on Sun, 16 Jul 2000 19:16:15 +0200 (MET DST)


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

Re: Wrong layout of the return value of gpow()?


In response to:
> Message-ID: <20000715231905.A23373@monk.mps.ohio-state.edu>
> Date: Sat, 15 Jul 2000 23:19:05 -0400
> From: Ilya Zakharevich <ilya@math.ohio-state.edu>
> References: <200007160101.DAA20011@sunscheurle3.mathematik.tu-muenchen.de>

[GN]
> > That is the normal arrangement -- the parent object is created
> > first, and its child object(s) is (are) created after it and
> > thus below it on the stack.
[IZ]
> This looks like my misunderstanding of the layout of objects on the
> stack.  I thought that "taking a continuous chunk of the stack"
> includes the object to be placed *after* the pointer to the object.
> Let me try again:
> 
>   oavma = avma;
>   RETVAL = pari_function(..);
>   navma = avma;
> 
> The (part of the) return value which sits on the stack fills the chunk
> between navma and oavma, but RETVAL can point anywhere between navma
> and oavma-1, right?

Right.  So if you want to transfer it elsewhere  (e.g. by cloning onto
the heap)  and adjust avma, make sure you transfer the entire object.
If you want to bypass the implicit allocation done by gclone(), you
can use brutcopy() directly for copying everything that needs copying
into existing memory, or imitate it at the perl level.  (Both functions
live in gen2.c).

> Math::Pari uses a (superior?) memory management comparing to gp.  The
> Perl objects which maps to GENs have the "on stack/heap" flag.  Those
> objects which point to the stack are joined into the linked list.
> When such an object is free()ed, then
> 
>   a) if the objects is the latest one, avma is corrected;
>   b) if the object is deeper in the chain, then the later objects
>      are first clone()ed to the heap, then the avma is corrected.

Looks to me as if this should work as described, as long as the linked
list is related to stack positions in a monotonic way, and as long as
on-stack sub-objects aren't shared among those delayed-on-stack objects
which are directly tracked through list pointers.  (In particular, one
list pointer should not refer to a subobject of the target object of
another list pointer.)  There are some ramifications related to things
like INTMOD moduli  (where many pari functions behave differently de-
pending on whether x[1] points into the stack or into the heap -- in
the latter case, the pointer will be re-used, in the former, the modulus
object itself will usually be copied)  but this shouldn't throw any
spanners into the works as long as the free()ing described above happens
only at times when Math::Pari is in control and no libpari function is
anywhere on the call stack.

Do you, or could you, keep track of the navma values each time a new
delayed-on-stack object is put onto the linked list?  Then you could
use the navma of the youngest object older than the one being freed
to adjust avma.  (This may not be the same as the oavma from the time
the object being freed was created, but anything between the two would
have to be garbage.)

Hope this helps!
Gerhard