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

[perl #89188] PVBM pad constants aren't BM

Thread Next
Father Chrysostomos via RT
June 30, 2013 23:22
[perl #89188] PVBM pad constants aren't BM
Message ID:
On Sun Apr 24 13:35:35 2011, wrote:
> This is a bug report for perl from,
> generated with the help of perlbug 1.36 running under perl 5.10.0.
> -----------------------------------------------------------------
> [Please enter your report here]
> Under ithreads:
> $ ./perl -Ilib -MDevel::Peek -e 'use constant PVBM => "Foo"; my $dummy
> = index "Foo", PVBM; Dump(PVBM)'
> SV = PVGV(0x88cd78) at 0x84a9d0
>   REFCNT = 1
>   IV = 0
>   NV = 0
>   PV = 0x8590d8 "Foo"\0
>   CUR = 3
>   LEN = 8
> That's very interesting, but why is it a PVGV *without* Boyer Moore
> data.
> [That rather convoluted piece of code by Ben Morrow produces a PVBM
> accessible
> to Perl space, something I didn't think was possible.]
> At least, it does without ithreads. With ithreads, something drops the
> useful
> part.

Perl 5.10.0’s sv.c:sv_setsv_flags has this:

    case SVt_PVGV:
	if (isGV_with_GP(sstr) && dtype <= SVt_PVGV) {
	    glob_assign_glob(dstr, sstr, dtype);
	/* SvVALID means that this PVGV is playing at being an FBM.  */
	if (stype == SVt_PVLV)
	    SvUPGRADE(dstr, SVt_PVNV);
	    SvUPGRADE(dstr, (svtype)stype);

So the destination gets upgraded to SVt_PVGV because that’s what the
source is.

Under bleadperl, since PVBMs are actually of type SVt_PVMG, we get that

$ ./perl -Ilib -MDevel::Peek -e 'use constant PVBM => "Foo"; my $dummy =
index "Foo", PVBM; Dump(PVBM)'
SV = PVMG(0x1b75050) at 0x1b41be0
  REFCNT = 1
  IV = 0
  NV = 0
  PV = 0x1b9feb0 "Foo"\0
  CUR = 3
  LEN = 16

(That is actually wasteful; sv_setsv_flags shouldn’t make the
destination a PVMG if it is not going to use the MAGIC field.)

Under ithreads, each const op gets its own copy of the constant.  It
gets copied if it is in use by another pad slot (each const op has a pad

When the op tree is initally constructed, the const ops have direct
pointers to the SVs.  Those SVs get relocated to the pad afterwards. 
That’s when the copying happens.

The constant created by ‘use constant’ has the PADMY flag on, because it
is a lexical variable inside  Hence, every mention of the
constant gets its own copy of the original, none of them being PVBMs, as
the Boyer-Moore (or Ben Morrow? :-) tables are not copied.

If we use BEGIN { $::{PVBM} = \"Foo" } to create the constant and the
very first use of it is in index(), then pp_index does get a BM scalar.
 But you  have to use a C debugger and Perl_sv_dump to see it.

The reason that const ops get their own copies of constants is that
flags on the *value* in a pad slot are used to determine whether a pad
slot is in use.

My sprout/padconst branch fixes this.  But it’s not quite ready yet, and
it is still controversial.  See, for instance,
<> and
the messages that follow.


Father Chrysostomos

via perlbug:  queue: perl5 status: new

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About