BrowserUk has asked for the wisdom of the Perl Monks concerning the following question:

I get confused about when it is necessary to use sv_2mortal() on the value returned by the various newSV* macros and when not.

Does anyone know of a reference to good explanation of this, or care to offer one?


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re: XS-ive Mortality. (or when to use sv_2mortal())
by salva (Canon) on Mar 13, 2006 at 20:57 UTC
    If you need a temp SV, you can create it with any of the newSV* macros (that return SVs with a reference count of 1), use it for whatever you want and finally decrement its reference count to release it:
    SV *tmp = newSVsv(foo); do_something(tmp); SvREFCNT_dec(tmp);
    The problem with this approach is what happens if something gets wrong inside do_something() and it calls croak. It longjmps to someplace in the perl core over your clean up code and you start leaking memory.

    To solve that, you can use sv_2mortal, it remembers the SV so that, when control leaves the XS in any way, SvREFCNT_dec gets automatically called on it. The previous code is best written as:

    SV *tmp = sv_2mortal(newSVsv(foo)); do_something(tmp); /* no clean up code required here */

    In reply to your question, when is it necessary to call sv_2 mortal?, the answer is always, unless you want the SV to survive the XS call (for instance if you are saving a reference to it inside a C struct or global variable).

    If you want to store it inside a perl container (AV or HV), the safe way to do it is:

    SV *tmp = sv_2mortal(newSVsv(foo)); if (av_store(av, ix, tmp)) SvREFCNT_inc(tmp);
    ... av can have some magic attached (if it is a tied array for instance) and call croak from inside the av_store, that's why you need to mortalize the SV first and later increment the ref count if the call to av_store doesn't fail.

    Anyway, in the API documentation (perlapi) you will find which functions change the reference count of SVs (or AVs, HVs, etc). It could be summarized as: no function touchs the ref count unless it is a constructor (which sets ref count to 1) or it is a ref count manipulation function (SvREFCNT_inc, SvREFCNT_dec, sv_2mortal). Update functions that manipulate containers (AVs, HVs or RVs) as a whole, update the refcounts of the contained elements as required, for instance, if an AV is cleared, its elements ref counts are decremented.

    You can also control when mortalized variables are freed, with the SAVETMPS and FREETMPS macros. For instance, if you are creating SVs inside a loop, and you mortalize them, they are not going to be freed until the sub returns, and if it is a big loop it is going to require a lot of memory. With those macros you can free mortalized SVs created inside the loop in every iteration so the same memory is used by your temps over and over. See perlcall for more details.

      Excellent. Thankyou.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
Re: XS-ive Mortality. (or when to use sv_2mortal())
by syphilis (Archbishop) on Mar 14, 2006 at 01:07 UTC
    It's not made any easier by what gets done behind the scenes:
    use warnings; use Inline C => Config => CLEAN_AFTER_BUILD => 0, BUILD_NOISY => 1; use Inline C => <<'EOC'; void foo1 (int x) { Inline_Stack_Vars; Inline_Stack_Reset; Inline_Stack_Push(sv_2mortal(newSVuv(x * 3))); Inline_Stack_Done; Inline_Stack_Return(1); } SV * foo2 (int x) { return newSVuv(x * 3); } EOC print foo1(7), "\n", foo2(8), "\n";
    Notice that foo1() specifically mortalises, while foo2() does not. Seems strange - but if you look at the C file that gets generated you'll see that the mortalisation got inserted into foo2() for you.

    Although I've used an Inline::C script as a demo, it's xsubpp behaviour - nothing to do with Inline at all.

    Cheers,
    Rob
Re: XS-ive Mortality. (or when to use sv_2mortal())
by rafl (Friar) on Mar 13, 2006 at 19:54 UTC

    From the perlguts manpage:

           There are some convenience functions available that 
           can help with the destruction of xVs.  These
           functions introduce the concept of "mortality".  An
           xV that is mortal has had its reference count marked
           to be decremented, but not actually decremented,
           until "a short time later".  Generally the term
           "short time later" means a single Perl statement,
           such as a call to an XSUB function.  The actual
           determinant for when mortal xVs have their reference
           count decremented depends on two macros, SAVETMPS and
           FREETMPS.  See perlcall and perlxs for more details
           on these macros.
    
           "Mortalization" then is at its simplest a deferred
           "SvREFCNT_dec".  However, if you mortalize a variable
           twice, the reference count will later be decremented
           twice.
    
           "Mortal" SVs are mainly used for SVs that are placed
           on perl's stack.  For example an SV which is created
           just to pass a number to a called sub is made mortal
           to have it cleaned up automatically when it's popped
           off the stack. Similarly, results returned by XSUBs
           (which are pushed on the stack) are often made
           mortal.
    

    Flo

      Yeah. Saw that, but it doesn't help much. The vagueness of

      Similarly, results returned by XSUBs (which are pushed on the stack) are often made mortal.

      leaves me wondering if I should mortalise every SV I return from XS code? What about from Inline C code? How about the RV that you bless and set into the object that you return a reference to when using Inline C OO? Or the reference itself?


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.