hv.c: add some NULL check removal
authorbulk88 (via RT) <perlbug-followup@perl.org>
Mon, 24 Dec 2012 02:20:10 +0000 (18:20 -0800)
committerDavid Mitchell <davem@iabyn.com>
Tue, 29 Jan 2013 11:16:44 +0000 (11:16 +0000)
The purpose is less machine instructions/faster code.

* S_hv_free_ent_ret() is always called with entry non-null: so change its
  signature to reflect this, and remove a null check;

* Add some SvREFCNT_dec_NNs;

* In hv_clear(), refactor the code slightly to only do a SvREFCNT_dec_NN
within the branch where its already been determined that the arg is
non-null; also, use the _nocontext variant of Perl_croak() to save
a push instruction in threaded perls.

embed.fnc
hv.c
proto.h

index e2229c0..2a7664d 100644 (file)
--- a/embed.fnc
+++ b/embed.fnc
@@ -1770,7 +1770,7 @@ po        |SV*    |hfree_next_entry       |NN HV *hv|NN STRLEN *indexp
 #if defined(PERL_IN_HV_C)
 s      |void   |hsplit         |NN HV *hv
 s      |void   |hfreeentries   |NN HV *hv
-s      |SV*    |hv_free_ent_ret|NN HV *hv|NULLOK HE *entry
+s      |SV*    |hv_free_ent_ret|NN HV *hv|NN HE *entry
 sa     |HE*    |new_he
 sanR   |HEK*   |save_hek_flags |NN const char *str|I32 len|U32 hash|int flags
 sn     |void   |hv_magic_check |NN HV *hv|NN bool *needs_copy|NN bool *needs_store
diff --git a/hv.c b/hv.c
index 966a12f..5f7ae85 100644 (file)
--- a/hv.c
+++ b/hv.c
@@ -1377,7 +1377,7 @@ Perl_hv_copy_hints_hv(pTHX_ HV *const ohv)
            else {
                (void)hv_common(hv, heksv, HeKEY(entry), HeKLEN(entry),
                                 HeKFLAGS(entry), HV_FETCH_ISSTORE|HV_FETCH_JUST_SV, sv, HeHASH(entry));
-               SvREFCNT_dec(heksv);
+               SvREFCNT_dec_NN(heksv);
            }
        }
        HvRITER_set(ohv, riter);
@@ -1399,8 +1399,6 @@ S_hv_free_ent_ret(pTHX_ HV *hv, HE *entry)
 
     PERL_ARGS_ASSERT_HV_FREE_ENT_RET;
 
-    if (!entry)
-       return NULL;
     val = HeVAL(entry);
     if (HeKLEN(entry) == HEf_SVKEY) {
        SvREFCNT_dec(HeKEY_sv(entry));
@@ -1481,14 +1479,15 @@ Perl_hv_clear(pTHX_ HV *hv)
            for (; entry; entry = HeNEXT(entry)) {
                /* not already placeholder */
                if (HeVAL(entry) != &PL_sv_placeholder) {
-                   if (HeVAL(entry) && SvREADONLY(HeVAL(entry))
-                    && !SvIsCOW(HeVAL(entry))) {
-                       SV* const keysv = hv_iterkeysv(entry);
-                       Perl_croak(aTHX_
-                                  "Attempt to delete readonly key '%"SVf"' from a restricted hash",
-                                  (void*)keysv);
+                   if (HeVAL(entry)) {
+                       if (SvREADONLY(HeVAL(entry)) && !SvIsCOW(HeVAL(entry))) {
+                           SV* const keysv = hv_iterkeysv(entry);
+                           Perl_croak_nocontext(
+                               "Attempt to delete readonly key '%"SVf"' from a restricted hash",
+                               (void*)keysv);
+                       }
+                       SvREFCNT_dec_NN(HeVAL(entry));
                    }
-                   SvREFCNT_dec(HeVAL(entry));
                    HeVAL(entry) = &PL_sv_placeholder;
                    HvPLACEHOLDERS(hv)++;
                }
diff --git a/proto.h b/proto.h
index 1953cae..2f03aa0 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -5709,9 +5709,10 @@ STATIC struct xpvhv_aux* S_hv_auxinit(HV *hv)
 
 STATIC SV*     S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, int k_flags, I32 d_flags, U32 hash);
 STATIC SV*     S_hv_free_ent_ret(pTHX_ HV *hv, HE *entry)
-                       __attribute__nonnull__(pTHX_1);
+                       __attribute__nonnull__(pTHX_1)
+                       __attribute__nonnull__(pTHX_2);
 #define PERL_ARGS_ASSERT_HV_FREE_ENT_RET       \
-       assert(hv)
+       assert(hv); assert(entry)
 
 STATIC void    S_hv_magic_check(HV *hv, bool *needs_copy, bool *needs_store)
                        __attribute__nonnull__(1)