From 042b41339aa3d3aae2c69bfb2b48ba665afcc863 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mattias=20Engdeg=C3=A5rd?= Date: Fri, 19 Jan 2024 16:45:51 +0100 Subject: [PATCH] Make better use of fixnum range in sxhash etc Recent hash table changes reduced the range of sxhash, sxhash-eq etc to [0,2**32) on platforms with 62-bit fixnums. This change makes them use the full fixnum range again. Hash table hashing is unaffected. * src/fns.c (sxhash_eq, sxhash_eql): New. (hash_hash_to_fixnum): Replace with... (reduce_emacs_uint_to_fixnum): ...this. (hashfn_eq, hashfn_eql, Fsxhash_eq, Fsxhash_eql, Fsxhash_equal) (Fsxhash_equal_including_properties): Use the new functions. (cherry picked from commit 50201e03b9c4133296dbd10e6c7ebd5dc2a62d50) --- src/fns.c | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/fns.c b/src/fns.c index f862c1470c4..f34e069ddbe 100644 --- a/src/fns.c +++ b/src/fns.c @@ -4462,14 +4462,26 @@ reduce_emacs_uint_to_hash_hash (EMACS_UINT x) : x ^ (x >> (8 * (sizeof x - sizeof (hash_hash_t))))); } +static EMACS_INT +sxhash_eq (Lisp_Object key) +{ + if (symbols_with_pos_enabled && SYMBOL_WITH_POS_P (key)) + key = SYMBOL_WITH_POS_SYM (key); + return XHASH (key) ^ XTYPE (key); +} + +static EMACS_INT +sxhash_eql (Lisp_Object key) +{ + return FLOATP (key) || BIGNUMP (key) ? sxhash (key) : sxhash_eq (key); +} + /* Ignore H and return a hash code for KEY which uses 'eq' to compare keys. */ static hash_hash_t hashfn_eq (Lisp_Object key, struct Lisp_Hash_Table *h) { - if (symbols_with_pos_enabled && SYMBOL_WITH_POS_P (key)) - key = SYMBOL_WITH_POS_SYM (key); - return reduce_emacs_uint_to_hash_hash (XHASH (key) ^ XTYPE (key)); + return reduce_emacs_uint_to_hash_hash (sxhash_eq (key)); } /* Ignore H and return a hash code for KEY which uses 'equal' to @@ -4484,8 +4496,7 @@ hashfn_equal (Lisp_Object key, struct Lisp_Hash_Table *h) static hash_hash_t hashfn_eql (Lisp_Object key, struct Lisp_Hash_Table *h) { - return (FLOATP (key) || BIGNUMP (key) - ? hashfn_equal (key, h) : hashfn_eq (key, h)); + return reduce_emacs_uint_to_hash_hash (sxhash_eql (key)); } /* Given H, return a hash code for KEY which uses a user-defined @@ -5283,13 +5294,11 @@ collect_interval (INTERVAL interval, void *arg) Lisp Interface ***********************************************************************/ -/* Reduce X to a Lisp fixnum. */ +/* Reduce the hash value X to a Lisp fixnum. */ static inline Lisp_Object -hash_hash_to_fixnum (hash_hash_t x) +reduce_emacs_uint_to_fixnum (EMACS_UINT x) { - return make_ufixnum (FIXNUM_BITS < 8 * sizeof x - ? (x ^ x >> (8 * sizeof x - FIXNUM_BITS)) & INTMASK - : x); + return make_ufixnum (SXHASH_REDUCE (x)); } DEFUN ("sxhash-eq", Fsxhash_eq, Ssxhash_eq, 1, 1, 0, @@ -5299,7 +5308,7 @@ If (eq A B), then (= (sxhash-eq A) (sxhash-eq B)). Hash codes are not guaranteed to be preserved across Emacs sessions. */) (Lisp_Object obj) { - return hash_hash_to_fixnum (hashfn_eq (obj, NULL)); + return reduce_emacs_uint_to_fixnum (sxhash_eq (obj)); } DEFUN ("sxhash-eql", Fsxhash_eql, Ssxhash_eql, 1, 1, 0, @@ -5310,7 +5319,7 @@ isn't necessarily true. Hash codes are not guaranteed to be preserved across Emacs sessions. */) (Lisp_Object obj) { - return hash_hash_to_fixnum (hashfn_eql (obj, NULL)); + return reduce_emacs_uint_to_fixnum (sxhash_eql (obj)); } DEFUN ("sxhash-equal", Fsxhash_equal, Ssxhash_equal, 1, 1, 0, @@ -5321,7 +5330,7 @@ opposite isn't necessarily true. Hash codes are not guaranteed to be preserved across Emacs sessions. */) (Lisp_Object obj) { - return hash_hash_to_fixnum (hashfn_equal (obj, NULL)); + return reduce_emacs_uint_to_fixnum (sxhash (obj)); } DEFUN ("sxhash-equal-including-properties", Fsxhash_equal_including_properties, @@ -5334,14 +5343,10 @@ If (sxhash-equal-including-properties A B), then Hash codes are not guaranteed to be preserved across Emacs sessions. */) (Lisp_Object obj) { + EMACS_UINT hash = sxhash (obj); if (STRINGP (obj)) - { - EMACS_UINT hash = 0; - traverse_intervals (string_intervals (obj), 0, hash_interval, &hash); - return make_ufixnum (SXHASH_REDUCE (sxhash_combine (sxhash (obj), hash))); - } - - return hash_hash_to_fixnum (hashfn_equal (obj, NULL)); + traverse_intervals (string_intervals (obj), 0, hash_interval, &hash); + return reduce_emacs_uint_to_fixnum (hash); } -- 2.39.5