develooper Front page | perl.perl5.porters | Postings from March 2013

Confusion about SvANY and Devel::Peek output

Thread Next
From:
demerphq
Date:
March 20, 2013 10:59
Subject:
Confusion about SvANY and Devel::Peek output
Message ID:
CANgJU+VbBMSJ14hbPjH6WtmqC6T7Sdct=5qnB4_73-mFMDMTag@mail.gmail.com
Consider  the following output:

$ perl -MDevel::Peek -e'my $x=1; Dump($x)'
SV = IV(0x1a5fbd8) at 0x1a5fbe0
  REFCNT = 1
  FLAGS = (PADMY,IOK,pIOK)
  IV = 1

I cannot understand the two pointer values there.  The first is
supposed to be the address in the sv_any field of an SV head. The
second is supposed to be the address of the SV head itself.

Since this is a bodyless SV, why does it output (0x1a5fbd8) as the
address for sv_any? Why is that address *before* the address of the SV
itself 0x1a5fbe0. Shouldnt it output:

SV = IV(0x0) at 0x1a5fbe0
  REFCNT = 1
  FLAGS = (PADMY,IOK,pIOK)
  IV = 1

Like undef does:

$ perl -MDevel::Peek -e'Dump(undef)'
SV = NULL(0x0) at 0x2541838
  REFCNT = 2147483599
  FLAGS = (READONLY)

This seems weird. I had always thought that an SvHEAD contained three
members, refcount, flags, and a pointer slot. And that we used the
pointer slot to store things like IV's in so we could avoid the
overhead of a body.

But it turns out an SvHEAD is four members, a pointer (sv_any),
sv_refcnt, sv_flags, and a union (sizeof(void*)) sv_u.

So what is going on here? Why cant we use sv_u instead of SvANY -
presumably there is a good reason or I expect Nicholas would have made
it happen already.

Another question this raises for me: why is SvANY _before_ the
refcount and flags? Id have expected the flags to be first, then the
refcount then the sv_any member.

Cheers,
Yves

Ps: Here is some of the code and defines involved:

The code that produces most of the first line of output from
Devel::Peek is as follows:

    d = Perl_newSVpvf(aTHX_
                   "(0x%"UVxf") at 0x%"UVxf"\n%*s  REFCNT =
%"IVdf"\n%*s  FLAGS = (",
                   PTR2UV(SvANY(sv)), PTR2UV(sv),
                   (int)(PL_dumpindent*level), "", (IV)SvREFCNT(sv),
                   (int)(PL_dumpindent*level), "");


So the (0x1a5fbd8) refers to the SvANY(sv), which is defined as

#define SvANY(sv)       (sv)->sv_any

The structure of an SV head is as follows:

/* start with 2 sv-head building blocks */
#define _SV_HEAD(ptrtype) \
    ptrtype     sv_any;         /* pointer to body */   \
    U32         sv_refcnt;      /* how many references to us */ \
    U32         sv_flags        /* what we are */

#define _SV_HEAD_UNION \
    union {                             \
        char*   svu_pv;         /* pointer to malloced string */        \
        IV      svu_iv;                 \
        UV      svu_uv;                 \
        SV*     svu_rv;         /* pointer to another SV */             \
        struct regexp* svu_rx;          \
        SV**    svu_array;              \
        HE**    svu_hash;               \
        GP*     svu_gp;                 \
        PerlIO *svu_fp;                 \
    }   sv_u


struct STRUCT_SV {              /* struct sv { */
    _SV_HEAD(void*);
    _SV_HEAD_UNION;






-- 
perl -Mre=debug -e "/just|another|perl|hacker/"

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About