improve hashing algorithm for ptr tables in perl_clone:
Dave Mitchell [Wed, 19 May 2004 21:02:04 +0000 (21:02 +0000)]
the bottom few bits of a pointer are usually zero

p4raw-id: //depot/perl@22831

sv.c

diff --git a/sv.c b/sv.c
index 4be4a7f..d776e15 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -10374,13 +10374,19 @@ Perl_ptr_table_new(pTHX)
     return tbl;
 }
 
+#if (PTRSIZE == 8)
+#  define PTR_TABLE_HASH(ptr) (PTR2UV(ptr) >> 3)
+#else
+#  define PTR_TABLE_HASH(ptr) (PTR2UV(ptr) >> 2)
+#endif
+
 /* map an existing pointer using a table */
 
 void *
 Perl_ptr_table_fetch(pTHX_ PTR_TBL_t *tbl, void *sv)
 {
     PTR_TBL_ENT_t *tblent;
-    UV hash = PTR2UV(sv);
+    UV hash = PTR_TABLE_HASH(sv);
     assert(tbl);
     tblent = tbl->tbl_ary[hash & tbl->tbl_max];
     for (; tblent; tblent = tblent->next) {
@@ -10399,7 +10405,7 @@ Perl_ptr_table_store(pTHX_ PTR_TBL_t *tbl, void *oldv, void *newv)
     /* XXX this may be pessimal on platforms where pointers aren't good
      * hash values e.g. if they grow faster in the most significant
      * bits */
-    UV hash = PTR2UV(oldv);
+    UV hash = PTR_TABLE_HASH(oldv);
     bool empty = 1;
 
     assert(tbl);
@@ -10440,7 +10446,7 @@ Perl_ptr_table_split(pTHX_ PTR_TBL_t *tbl)
            continue;
        curentp = ary + oldsize;
        for (entp = ary, ent = *ary; ent; ent = *entp) {
-           if ((newsize & PTR2UV(ent->oldval)) != i) {
+           if ((newsize & PTR_TABLE_HASH(ent->oldval)) != i) {
                *entp = ent->next;
                ent->next = *curentp;
                *curentp = ent;