From: Nicholas Clark Date: Fri, 27 Feb 2004 10:41:39 +0000 (+0000) Subject: In hsplit, if a normal hash has placeholders then clear them before X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=18026298eff2588a08fb9adea03ddb6fd64c650b;p=p5sagit%2Fp5-mst-13.2.git In hsplit, if a normal hash has placeholders then clear them before splitting. We can do this safely because Storable ensures hsplit is not called while it builds restricted hashes (actually any hashes) This change may not make things faster, but now we have the choice. p4raw-id: //depot/perl@22393 --- diff --git a/ext/Storable/t/restrict.t b/ext/Storable/t/restrict.t index 9359f21..58c1004 100644 --- a/ext/Storable/t/restrict.t +++ b/ext/Storable/t/restrict.t @@ -38,7 +38,7 @@ sub BEGIN { use Storable qw(dclone); use Hash::Util qw(lock_hash unlock_value); -print "1..16\n"; +print "1..50\n"; my %hash = (question => '?', answer => 42, extra => 'junk', undef => undef); lock_hash %hash; @@ -100,4 +100,23 @@ for $Storable::canonical (0, 1) { testit (\%hash); my $object = \%hash; # bless {}, "Restrict_Test"; + + my %hash2; + $hash2{"k$_"} = "v$_" for 0..16; + lock_hash %hash2; + for (0..16) { + unlock_value %hash2, "k$_"; + delete $hash2{"k$_"}; + } + my $copy = dclone \%hash2; + + for (0..16) { + my $k = "k$_"; + eval { $copy->{$k} = undef } ; + unless (ok ++$test, !$@, "Can assign to reserved key '$k'?") { + my $diag = $@; + $diag =~ s/\n.*\z//s; + print "# \$\@: $diag\n"; + } + } } diff --git a/hv.c b/hv.c index 28c04de..cebf2f9 100644 --- a/hv.c +++ b/hv.c @@ -1038,11 +1038,6 @@ S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, STATIC void S_hsplit(pTHX_ HV *hv) { - /* Can't make this clear any placeholders first for non-restricted hashes, - as Storable rebuilds restricted hashes by putting in all the - placeholders (first) before turning on the readonly flag. Hence midway - through restoring the hash there are placeholders which need to remain - even though the hash isn't (currently) flagged as restricted. */ register XPVHV* xhv = (XPVHV*)SvANY(hv); I32 oldsize = (I32) xhv->xhv_max+1; /* HvMAX(hv)+1 (sick) */ register I32 newsize = oldsize * 2; @@ -1055,6 +1050,17 @@ S_hsplit(pTHX_ HV *hv) int longest_chain = 0; int was_shared; + /*PerlIO_printf(PerlIO_stderr(), "hsplit called for %p which had %d\n", + hv, (int) oldsize);*/ + + if (HvPLACEHOLDERS(hv) && !SvREADONLY(hv)) { + /* Can make this clear any placeholders first for non-restricted hashes, + even though Storable rebuilds restricted hashes by putting in all the + placeholders (first) before turning on the readonly flag, because + Storable always pre-splits the hash. */ + hv_clear_placeholders(hv); + } + PL_nomemok = TRUE; #if defined(STRANGE_MALLOC) || defined(MYMALLOC) Renew(a, PERL_HV_ARRAY_ALLOC_BYTES(newsize), char);