On Sat, Mar 05, 2005 at 09:08:19AM -0500, muppet wrote:
> sv_2mortal() (Perl_sv_2mortal in sv.c) pushes the sv onto the tmps 
> stack and marks it with SvTEMP_on().  the temps stack is cleaned up 
> when exiting the current context.  its refcount is not actually 
> modified.

Which I discovered after an hour or so of bug hunting are actually two
independent actions. (frustratingly)

Pushing (a pointer to) an SV onto the tmps stack means that 1 reference to
it is released at context exit, which will free it, assuming that there were
no other references.

While marking something with SvTEMP_on() has at least 1 side effect - the
string buffer can be "stolen" if that scalar is copied to another scalar,
on the assumption that it's a temporary and would not be needed after the
end of context.

What I was trying to do (and this may be the wrong way to do this) was trying
to donate the last reference to something to the tmps stack to ensure that it
would get cleaned up come what may (ie die() in the next bit of code). But
the code needed the string value at least twice, and my change caused obscure
regression test failures until I worked out the implications of SvTEMP_on().

This is why you find this glorious piece of code in newSVsv:

    if (SvTEMP(old)) {
        SvTEMP_off(old);
        sv_setsv(sv,old);
        SvTEMP_on(old);
    }
    else
        sv_setsv(sv,old);

to ensure that sv_setsv doesn't steal the temporary.

Well, you did until I refactored out the inefficiency. (between 5.8.5 and
5.8.6, IIRC)

Nicholas Clark

Reply via email to