This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Stop shared hash key TARGs from being shared
authorFather Chrysostomos <sprout@cpan.org>
Wed, 3 Jul 2013 01:18:13 +0000 (18:18 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Fri, 26 Jul 2013 06:48:02 +0000 (23:48 -0700)
commit5d7191988b7898f8bbf2cb7fe55bcad6416c3e9c
treeec28f973d92efbf6cb283c49c6f9fd9cbe5b1835
parent137da2b05b4b7628115049f343163bdaf2c30dbb
Stop shared hash key TARGs from being shared

A CV has a list of pads containing a different pad for each recursion
level.  pad_push, which adds a new pad to the list, copies some items
from pad no. 1 but not others.  In particular op targets¹ are created
anew, but, under ithreads, constants² are not.  Historically, these
were distinguished from each other by flags on the value.  Any read-
only or shared hash key scalar was considered to be a constant, and
hence shared between pads.  The target returned by ref() is a shared
hash key scalar, so it was being shared between recursion levels.
Recent commits have made it possible to distinguish between constants
and targets based on the name.  Formerly, both were nameless pad
entries.  Now constants have zero-length names (PadnamePV(name) &&
!PadnameLEN(name)).  So we can use that to fix this bug.

¹ Many operators return the same scalar each time, for efficiency.
  This is stored in the pad, and is known as the target, or TARG.
² Constanst are stored in the pad under ithreads, instead of being
  attached directly to ops, as they are under non-threaded builds.
pad.c
t/op/sub.t