summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embed.fnc1
-rw-r--r--embed.h1
-rw-r--r--proto.h6
-rw-r--r--util.c36
4 files changed, 43 insertions, 1 deletions
diff --git a/embed.fnc b/embed.fnc
index e9c88a017c..a0efe86d35 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -5893,6 +5893,7 @@ S |void |warn_on_first_deprecated_use \
#if defined(PERL_IN_UTIL_C)
S |bool |ckwarn_common |U32 w
S |SV * |mess_alloc
+Ti |U32 |ptr_hash |PTRV u
S |SV * |with_queued_errors \
|NN SV *ex
So |void |xs_version_bootcheck \
diff --git a/embed.h b/embed.h
index d7c7da459a..c27c109623 100644
--- a/embed.h
+++ b/embed.h
@@ -1636,6 +1636,7 @@
# if defined(PERL_IN_UTIL_C)
# define ckwarn_common(a) S_ckwarn_common(aTHX_ a)
# define mess_alloc() S_mess_alloc(aTHX)
+# define ptr_hash S_ptr_hash
# define with_queued_errors(a) S_with_queued_errors(aTHX_ a)
# if defined(PERL_MEM_LOG) && !defined(PERL_MEM_LOG_NOIMPL)
# define mem_log_common S_mem_log_common
diff --git a/proto.h b/proto.h
index 909dccae90..358da8ca3f 100644
--- a/proto.h
+++ b/proto.h
@@ -9538,6 +9538,12 @@ S_mem_log_common(enum mem_log_type mlt, const UV n, const UV typesize, const cha
assert(type_name); assert(filename); assert(funcname)
# endif /* defined(PERL_MEM_LOG) && !defined(PERL_MEM_LOG_NOIMPL) */
+# if !defined(PERL_NO_INLINE_FUNCTIONS)
+PERL_STATIC_INLINE U32
+S_ptr_hash(PTRV u);
+# define PERL_ARGS_ASSERT_PTR_HASH
+
+# endif /* !defined(PERL_NO_INLINE_FUNCTIONS) */
# if defined(PERL_USES_PL_PIDSTATUS)
STATIC void
S_pidgone(pTHX_ Pid_t pid, int status);
diff --git a/util.c b/util.c
index cedde45120..b5721173e1 100644
--- a/util.c
+++ b/util.c
@@ -4592,6 +4592,39 @@ Perl_parse_unicode_opts(pTHX_ const char **popt)
# include <starlet.h>
#endif
+/* hash a pointer and return a U32
+ *
+ * this code was derived from Sereal, which was derived from autobox.
+ */
+
+PERL_STATIC_INLINE U32 S_ptr_hash(PTRV u) {
+#if PTRSIZE == 8
+ /*
+ * This is one of Thomas Wang's hash functions for 64-bit integers from:
+ * http://www.concentric.net/~Ttwang/tech/inthash.htm
+ */
+ u = (~u) + (u << 18);
+ u = u ^ (u >> 31);
+ u = u * 21;
+ u = u ^ (u >> 11);
+ u = u + (u << 6);
+ u = u ^ (u >> 22);
+#else
+ /*
+ * This is one of Bob Jenkins' hash functions for 32-bit integers
+ * from: http://burtleburtle.net/bob/hash/integer.html
+ */
+ u = (u + 0x7ed55d16) + (u << 12);
+ u = (u ^ 0xc761c23c) ^ (u >> 19);
+ u = (u + 0x165667b1) + (u << 5);
+ u = (u + 0xd3a2646c) ^ (u << 9);
+ u = (u + 0xfd7046c5) + (u << 3);
+ u = (u ^ 0xb55a4f09) ^ (u >> 16);
+#endif
+ return (U32)u;
+}
+
+
U32
Perl_seed(pTHX)
{
@@ -4660,7 +4693,8 @@ Perl_seed(pTHX)
u += SEED_C3 * (U32)PerlProc_getpid();
u += SEED_C4 * (U32)PTR2UV(PL_stack_sp);
#ifndef PLAN9 /* XXX Plan9 assembler chokes on this; fix needed */
- u += SEED_C5 * (U32)PTR2UV(&when);
+ UV ptruv = PTR2UV(&when);
+ u += SEED_C5 * ptr_hash(ptruv);
#endif
return u;
}