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

[perl #117299] keys are readonly in perl 5.14.2!

Father Chrysostomos via RT
July 21, 2013 18:44
[perl #117299] keys are readonly in perl 5.14.2!
Message ID:
On Mon Jun 03 22:45:16 2013, demerphq wrote:
> The point I refer to is that you made read-only keys no longer have
> the read only flag set.
> This means that old code that tests for read-onlyness will mindlessly
> modify read only data structures, which is an unacceptable failure
> mode.
> How it affected HTML::Entities is just a symptom of a dangerous
> non-backwards compatible change that cannot persist in 5.20.

I still disagree with you.  I am going to try and persuade you to change
you mind. :-)

In my experience, most XS code simply does not modify string buffers
directly, but uses sv_set* and sv_cat*.

Most of the code I have seen that modifies SvPVX in place is old code
that predates the API.  And then much of what I have seen was already
buggy anyway.

I also find it unconvincing that the presence of the SvREADONLY flag is
a panacea that allays all such problems with corrupted buffers.  I found
more than a dozen bugs, both in core and on CPAN, where the read-only
flag was simply ignored.  And it wasn’t the end of the world.

If copy-on-write is to become more prevalent, then under the
READONLY+FAKE system almost every piece of XS code is going to have to
do if (SvREADONLY && !SvFAKE).  Believe me, you will see dozens of
tickets on about ‘Modification of a read-only value’ under 5.20.

Anyway, the point I am trying to get to is that there are certain
optimisations I would like to implement, involving read-only COWs, that
I cannot do if there is a chance the flags will be reverted back to the
way they used to work.

According to the READONLY+FAKE scheme, it is not possible to have a COW
that is read-only to Perl space.  Or, it is not possible to do COW with
read-only scalars.

That means that $x = "hello" will always copy the buffer.  It also means
that $x = "h"."ello" will copy the buffer, but disabling the constant
folding ($x = ${\"h"}."ello") allows the buffer not to be copied,
speeding things up.

$ time ./perl -Ilib -e '$x = " "x2**31'

real	0m32.062s
user	0m2.832s
sys	0m3.578s
$ time ./perl -Ilib -e '$x = ${\" "}x2**31'

real	0m2.635s
user	0m1.157s
sys	0m1.409s

Some people lock their objects supposedly for the sake of speed
(avoiding extra copies), but Hash::Util::lock_value (i.e.,
Internals::SvREADONLY) forces the string to be copied if it is COW,
defeating the purpose.

All this can be cleaned up if we allow read-only COWs, which cannot
happen if SvREADONLY means two things.


Father Chrysostomos

via perlbug:  queue: perl5 status: open Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About