This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Make hv_undef leave HvENAME alone
authorFather Chrysostomos <sprout@cpan.org>
Sat, 20 Nov 2010 19:33:59 +0000 (11:33 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 21 Nov 2010 02:15:14 +0000 (18:15 -0800)
commit745edda6f1b4ede54e0225b4d1528e96dc0217a0
tree46beee2506a78623adaa057176519956408dfbb6
parent8581adba64260d29041e9d7dc923a10b2ab2424f
Make hv_undef leave HvENAME alone

unless called from sv_clear.

This is necessary as and undeffed stash, though it nominally becomes
just a plain hash and is not a stash any more, is still to be found
in the symbol table. It may even be in multiple places. HvENAME’s
raison d’être is to keep track of this. If the effective name is
deleted, then things can get out of sync as the test in the commit
demonstrates. This can cause problems if the hash is turned back
into a stash.

This does not change the deletion of the HvNAME, which is the only
difference between hv_clear and hv_undef on stashes that is visible
from Perl. caller still returns (unknown) or __ANON__::....

I tried to make this into several small commits, but each part of it
breaks things without the other parts, so this is one big commit.

These are the various parts:

• hv_undef no longer calls mro_package_named directly, as it deletes
  the effective name of the stash. It must only be called on sub-
  stashes, so hfreeentries has been modified to do that.

• hv_name_set, which has erased the HvENAME when passed a null arg
  for the value ever since effective names were added (a special case
  put it just for hv_undef), now leaves the HvENAME alone, unless the
  new HV_NAME_SETALL flag (set to 2 to allow for UTF8 in future)
  is passed.

• hv_undef does not delete the name before the call to hfreeentries
  during global destruction. That extra name deletion was added when
  hfreeentries stopped hiding the name, as CVs won’t be anonymised
  properly if they see it. It does not matter where the CVs point if
  they are to be freed shortly. This is just a speed optimisation, as
  it allows the name and effective name to be deleted in one fell
  swoop. Deleting just the name (not the effective name) can require a
  memory allocation.

• hv_undef calls mro_isa_changed_in as it used to (before it started
  using mro_package_moved), but now it happens after the entries are
  freed. Calling it first, as 5.13.6 and earlier versions did, was
  simply wrong.

• Both names are deleted from PL_stashcache. I inadvertently switched
  it back and forth between the two names in previous commits. Since
  it needed to be accounted for, it made no omit it, as that would
  just complicate things. (I think PL_stashcache is buggy, though I
  have yet to come up with a test case.)

• sv_clear now calls Perl_hv_undef_flags with the HV_NAME_SETALL
  flag, which is passed through to the second hv_name_set call,
  after hfreeentries. That determines whether the effective names
  are deleted.

• The changes at the end of hv_undef consist of pussyfooting to avoid
  unnecessary work. They make sure that everything is freed that needs
  to be and nothing is freed that must not be.
hv.c
hv.h
sv.c
t/mro/package_aliases.t