----------------------------------------
> Date: Wed, 25 Sep 2013 12:14:22 -0700
> Subject: Re: Avoid using PL_na with newSVpv
> From: j...@activestate.com
> To: kaffeeti...@gmx.de
> CC: perl-xs@perl.org
>
> On Wed, Sep 25, 2013 at 12:04 PM, Torsten Schoenfeld <kaffeeti...@gmx.de> 
> wrote:
>> Probably not. But <http://grep.cpan.me/?q=newSVpv.*PL_na> does show
>> quite a few hits, only roughly half of which are mine. Since the bugs
>> this causes are hard to diagnose, I thought a public service
>> announcement is appropriate.
>
> Hmm, maybe you should email the maintainers of those modules directly
> (or file bugs), if you have the time? perl-xs is kind of an obscure
> list, so it is unlikely they will actually see this thread.
>
>> I think I simply assumed that "na" stood for "not available". So I took
>> PL_na as a readability-improving alias for zero.
>
> I think in this case it means "not applicable", meaning "I don't care
> what the value is".
>
> Cheers,
> -Jan

I've thought for having, on 32 bit perl builds ONLY due to ABI issues, remove 
" STRLEN *const lp" from "Perl_sv_2pv_flags" and instead have it ALWAYS
return the length in the return value. 
struct 2pvret {
    char * pvx;
   STRLEN len;
}
______________________________
//fPerl_sv_2pv_flags sample
struct 2pvret ret;
    if (SvPOKp(sv)) {
      ret.len = SvCUR(sv);
    if (flags & SV_MUTABLE_RETURN) { 
        ret.pvx = SvPVX_mutable(sv);
       return ret;
    }
    if (flags & SV_CONST_RETURN) {
        ret.pvx =  (char *)SvPVX_const(sv);

       return ret;

    }
    ret.pvx = SvPVX(sv);
   return ret;
    }
___________________________________

then in the caller in a STATIC INLINE func
replace existing
_____________________________________
#define SvPV_flags(sv, lp, flags) \
    (SvPOK_nog(sv) \
     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv_flags(sv, &lp, flags))
________________________________________
with
________________________________________
#define SvPV_flags(sv, lp, flags)  SvPV_flags_real(sv, &lp, flags)
STATIC INLINE  char * SvPV_flags_real (SV * sv, STRLEN *const lp, const I32 
flags) {
     if(SvPOK_nog(sv)) {
          *lp = SvCUR(sv);
         return  SvPVX(sv);
     } else {
           struct 2pvret ret = sv_2pv_flags(sv, flags);
           *lp = ret.len;
          return ret.pvx;
    }
}
______________________________________

When the above is inlined, all the copies and &s will be optimized away.
the length will come back in volatile register edx. The char * will come back
in eax as it always has. If the caller doesn't want length, it can just assign 
something else to edx immediately. There is no reason to reserve a C 
stack location to do &,  in the rare case that 2pv_flags needs to be called.

I tried this a while ago, using so much inlining that 2pv_flags become 
undebuggable since it was reinterfaced into the return struct by value. It 
saved like 1 KB of machine code in perl519.dll when I tried it,                 
                          

Reply via email to