aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMattias EngdegÄrd2024-01-19 16:45:51 +0100
committerMattias EngdegÄrd2024-01-21 11:21:51 +0100
commit50201e03b9c4133296dbd10e6c7ebd5dc2a62d50 (patch)
tree7a703926319f43833c026652c8e669f08eb916a3 /src
parent7a87ca09a73d61b46bfcaca317095ce7545bd3f3 (diff)
downloademacs-50201e03b9c4133296dbd10e6c7ebd5dc2a62d50.tar.gz
emacs-50201e03b9c4133296dbd10e6c7ebd5dc2a62d50.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/fns.c45
1 files 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)
4462 : x ^ (x >> (8 * (sizeof x - sizeof (hash_hash_t))))); 4462 : x ^ (x >> (8 * (sizeof x - sizeof (hash_hash_t)))));
4463} 4463}
4464 4464
4465static EMACS_INT
4466sxhash_eq (Lisp_Object key)
4467{
4468 if (symbols_with_pos_enabled && SYMBOL_WITH_POS_P (key))
4469 key = SYMBOL_WITH_POS_SYM (key);
4470 return XHASH (key) ^ XTYPE (key);
4471}
4472
4473static EMACS_INT
4474sxhash_eql (Lisp_Object key)
4475{
4476 return FLOATP (key) || BIGNUMP (key) ? sxhash (key) : sxhash_eq (key);
4477}
4478
4465/* Ignore H and return a hash code for KEY which uses 'eq' to compare keys. */ 4479/* Ignore H and return a hash code for KEY which uses 'eq' to compare keys. */
4466 4480
4467static hash_hash_t 4481static hash_hash_t
4468hashfn_eq (Lisp_Object key, struct Lisp_Hash_Table *h) 4482hashfn_eq (Lisp_Object key, struct Lisp_Hash_Table *h)
4469{ 4483{
4470 if (symbols_with_pos_enabled && SYMBOL_WITH_POS_P (key)) 4484 return reduce_emacs_uint_to_hash_hash (sxhash_eq (key));
4471 key = SYMBOL_WITH_POS_SYM (key);
4472 return reduce_emacs_uint_to_hash_hash (XHASH (key) ^ XTYPE (key));
4473} 4485}
4474 4486
4475/* Ignore H and return a hash code for KEY which uses 'equal' to 4487/* 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)
4484static hash_hash_t 4496static hash_hash_t
4485hashfn_eql (Lisp_Object key, struct Lisp_Hash_Table *h) 4497hashfn_eql (Lisp_Object key, struct Lisp_Hash_Table *h)
4486{ 4498{
4487 return (FLOATP (key) || BIGNUMP (key) 4499 return reduce_emacs_uint_to_hash_hash (sxhash_eql (key));
4488 ? hashfn_equal (key, h) : hashfn_eq (key, h));
4489} 4500}
4490 4501
4491/* Given H, return a hash code for KEY which uses a user-defined 4502/* Given H, return a hash code for KEY which uses a user-defined
@@ -5283,13 +5294,11 @@ collect_interval (INTERVAL interval, void *arg)
5283 Lisp Interface 5294 Lisp Interface
5284 ***********************************************************************/ 5295 ***********************************************************************/
5285 5296
5286/* Reduce X to a Lisp fixnum. */ 5297/* Reduce the hash value X to a Lisp fixnum. */
5287static inline Lisp_Object 5298static inline Lisp_Object
5288hash_hash_to_fixnum (hash_hash_t x) 5299reduce_emacs_uint_to_fixnum (EMACS_UINT x)
5289{ 5300{
5290 return make_ufixnum (FIXNUM_BITS < 8 * sizeof x 5301 return make_ufixnum (SXHASH_REDUCE (x));
5291 ? (x ^ x >> (8 * sizeof x - FIXNUM_BITS)) & INTMASK
5292 : x);
5293} 5302}
5294 5303
5295DEFUN ("sxhash-eq", Fsxhash_eq, Ssxhash_eq, 1, 1, 0, 5304DEFUN ("sxhash-eq", Fsxhash_eq, Ssxhash_eq, 1, 1, 0,
@@ -5299,7 +5308,7 @@ If (eq A B), then (= (sxhash-eq A) (sxhash-eq B)).
5299Hash codes are not guaranteed to be preserved across Emacs sessions. */) 5308Hash codes are not guaranteed to be preserved across Emacs sessions. */)
5300 (Lisp_Object obj) 5309 (Lisp_Object obj)
5301{ 5310{
5302 return hash_hash_to_fixnum (hashfn_eq (obj, NULL)); 5311 return reduce_emacs_uint_to_fixnum (sxhash_eq (obj));
5303} 5312}
5304 5313
5305DEFUN ("sxhash-eql", Fsxhash_eql, Ssxhash_eql, 1, 1, 0, 5314DEFUN ("sxhash-eql", Fsxhash_eql, Ssxhash_eql, 1, 1, 0,
@@ -5310,7 +5319,7 @@ isn't necessarily true.
5310Hash codes are not guaranteed to be preserved across Emacs sessions. */) 5319Hash codes are not guaranteed to be preserved across Emacs sessions. */)
5311 (Lisp_Object obj) 5320 (Lisp_Object obj)
5312{ 5321{
5313 return hash_hash_to_fixnum (hashfn_eql (obj, NULL)); 5322 return reduce_emacs_uint_to_fixnum (sxhash_eql (obj));
5314} 5323}
5315 5324
5316DEFUN ("sxhash-equal", Fsxhash_equal, Ssxhash_equal, 1, 1, 0, 5325DEFUN ("sxhash-equal", Fsxhash_equal, Ssxhash_equal, 1, 1, 0,
@@ -5321,7 +5330,7 @@ opposite isn't necessarily true.
5321Hash codes are not guaranteed to be preserved across Emacs sessions. */) 5330Hash codes are not guaranteed to be preserved across Emacs sessions. */)
5322 (Lisp_Object obj) 5331 (Lisp_Object obj)
5323{ 5332{
5324 return hash_hash_to_fixnum (hashfn_equal (obj, NULL)); 5333 return reduce_emacs_uint_to_fixnum (sxhash (obj));
5325} 5334}
5326 5335
5327DEFUN ("sxhash-equal-including-properties", Fsxhash_equal_including_properties, 5336DEFUN ("sxhash-equal-including-properties", Fsxhash_equal_including_properties,
@@ -5334,14 +5343,10 @@ If (sxhash-equal-including-properties A B), then
5334Hash codes are not guaranteed to be preserved across Emacs sessions. */) 5343Hash codes are not guaranteed to be preserved across Emacs sessions. */)
5335 (Lisp_Object obj) 5344 (Lisp_Object obj)
5336{ 5345{
5346 EMACS_UINT hash = sxhash (obj);
5337 if (STRINGP (obj)) 5347 if (STRINGP (obj))
5338 { 5348 traverse_intervals (string_intervals (obj), 0, hash_interval, &hash);
5339 EMACS_UINT hash = 0; 5349 return reduce_emacs_uint_to_fixnum (hash);
5340 traverse_intervals (string_intervals (obj), 0, hash_interval, &hash);
5341 return make_ufixnum (SXHASH_REDUCE (sxhash_combine (sxhash (obj), hash)));
5342 }
5343
5344 return hash_hash_to_fixnum (hashfn_equal (obj, NULL));
5345} 5350}
5346 5351
5347 5352