This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
assume cleared hv can't be re-blessed
authorDavid Mitchell <davem@iabyn.com>
Wed, 11 May 2011 14:31:40 +0000 (15:31 +0100)
committerDavid Mitchell <davem@iabyn.com>
Thu, 19 May 2011 13:49:44 +0000 (14:49 +0100)
followup to previous commit. I'm fairly confident now that a HV being
freed in sv_clear() can never get re-blessed, and thus its SvSTASH field is
*always* safe to use.

The logic behind this is that once you get to sv_clear(), the HV has a
refcnt of zero, which means either:

* nothing references this, so there's no way to bless it;
* we're in SVf_BREAK territory, in which case something may still
  hold a reference to it, but all destructors will have already been
  called, so nothing can call bless.

sv.c

diff --git a/sv.c b/sv.c
index d78f776..6efcc8f 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -6290,11 +6290,9 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
                if (!sv) { /* no more elements of current HV to free */
                    sv = iter_sv;
                    type = SvTYPE(sv);
-                   /* Restore previous value of iter_sv, squirrelled away.
-                   /* Check whether someone has in the meantime used the
-                    * "unused" SvSTASH slot. If so, we'll just have to
-                    * abandon the old sv */
-                   iter_sv = SvOBJECT(sv) ? NULL : (SV*)SvSTASH(sv);
+                   /* Restore previous value of iter_sv, squirrelled away */
+                   assert(!SvOBJECT(sv));
+                   iter_sv = (SV*)SvSTASH(sv);
 
                    /* ideally we should restore the old hash_index here,
                     * but we don't currently save the old value */