]> git.eshelyaron.com Git - emacs.git/commitdiff
Make better use of fixnum range in sxhash etc
authorMattias EngdegÄrd <mattiase@acm.org>
Fri, 19 Jan 2024 15:45:51 +0000 (16:45 +0100)
committerEshel Yaron <me@eshelyaron.com>
Mon, 22 Jan 2024 16:54:36 +0000 (17:54 +0100)
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

index f862c1470c4b34a2e66a5a6535c6c7222208503e..f34e069ddbef44e3f5a00c8c842c9ecd75632fe8 100644 (file)
--- 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);
 }