RE: Avoid using PL_na with newSVpv

[email protected] (bulk 88)
Newsgroups perl.xs
Message-ID <[email protected]>
----------------------------------------
> Date: Wed, 25 Sep 2013 12:14:22 -0700
> Subject: Re: Avoid using PL_na with newSVpv
> From: [email protected]
> To: [email protected]
> CC: [email protected]
>
> On Wed, Sep 25, 2013 at 12:04 PM, Torsten Schoenfeld <[email protected]> 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,
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.