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

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

Thread Next
From:
Father Chrysostomos via RT
Date:
June 30, 2013 23:22
Subject:
[perl #89188] PVBM pad constants aren't BM
Message ID:
rt-3.6.HEAD-2552-1372634533-1141.89188-15-0@perl.org
On Sun Apr 24 13:35:35 2011, nick@eris.etla.org wrote:
> 
> This is a bug report for perl from nick@eris.etla.org,
> 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
>   FLAGS = (PADTMP,POK,READONLY,pPOK)
>   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);
	    return;
	}
	/* SvVALID means that this PVGV is playing at being an FBM.  */
	/*FALLTHROUGH*/
...
	if (stype == SVt_PVLV)
	    SvUPGRADE(dstr, SVt_PVNV);
	else
	    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
instead:

$ ./perl -Ilib -MDevel::Peek -e 'use constant PVBM => "Foo"; my $dummy =
index "Foo", PVBM; Dump(PVBM)'
SV = PVMG(0x1b75050) at 0x1b41be0
  REFCNT = 1
  FLAGS = (PADTMP,POK,READONLY,pPOK)
  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
slot).

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 constant.pm.  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,
<https://rt.perl.org/rt3/Ticket/Display.html?id=109744#txn-1225649> and
the messages that follow.


-- 

Father Chrysostomos


---
via perlbug:  queue: perl5 status: new
https://rt.perl.org:443/rt3/Ticket/Display.html?id=89188

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