in reply to Re^2: XS: Manipulating refcounts
in thread XS: Manipulating refcounts

Beautifully done, Animator. Your rewrite establishes that what I'd hoped to do is possible. It's clearer IMHO as well. :)

My crucial error was misunderstanding the return value of sv_setref_pv. I'd thought it returned the object rather than the reference. Once artist->perlobj is assigned the correct value, everything falls into place, as you show. Now I can go implement this algo. Brilliant!

you return the SV. Because of some XS magic (I think) a new SV is created with the contents of the perlref SV,

Here's how things progress behind the scenes as control leaves new_artist and we enter XS_main_new_artist, the glue function generated by Inline::C/xsubpp:

XS(XS_main_new_artist) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: main::new_artist(name)"); PERL_UNUSED_VAR(cv); /* -W */ { char * name = (char *)SvPV_nolen(ST(0)); SV * RETVAL; RETVAL = new_artist(name); ST(0) = RETVAL; sv_2mortal(ST(0)); } XSRETURN(1); }
  1. The return value from new_artist is copied to RETVAL, which is copied in turn to ST(0), the top of the perl stack.
  2. ST(0) is "mortalized" by calling sv_2mortal( ST(0) ). That's essentially a delayed decrement of its refcount. It won't be freed right away as would be the case if you'd called SvREFCNT_dec -- instead, the cleanup will occur a bit later, after we've had the chance to do something with it.
  3. XSRETURN(1) is invoked, indicating that a single value is being returned via the stack, and control leaves XS land, heading back into world of stock Perl OPs.
  4. The Perl assignment operator = pops the top item off the stack and triggers a call to SvSetMagicSV, and the value of the popped SV is copied into the lexical variable $artist. Now the SV that we created back in new_artist can be freed. (Note that since the Perl interpreter can often tell when an SV is about to be freed, it will probably "steal" the contents and avoid doing unneeded memory allocation and copying).

Now, consider that in my original program, the mortalized SV on the stack is the same SV that's housed in the Artist struct. I don't fully understand how reference counts affect things in such cases, but that was definitely not what I intended. It does not surprise me that undesirable consequences arose.

Thanks for your help,

--
Marvin Humphrey
Rectangular Research ― http://www.rectangular.com