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