aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-05-30 23:05:00 -0700
committerPaul Eggert2011-05-30 23:05:00 -0700
commit0de4bb688da4961269edab53dc0e0d5a30c01a44 (patch)
tree10e3c4d22f03496bf5b8fc4a41ee04cfcc52e33d /src
parentb9627cfb1d5b5b0914525a19cd9edb06f91a1665 (diff)
downloademacs-0de4bb688da4961269edab53dc0e0d5a30c01a44.tar.gz
emacs-0de4bb688da4961269edab53dc0e0d5a30c01a44.zip
Remove arbitrary limit of 2**31 entries in hash tables.
* category.c (hash_get_category_set): Use 'EMACS_UINT' and 'EMACS_INT' for hashes and hash indexes, instead of 'unsigned' and 'int'. * ccl.c (ccl_driver): Likewise. * charset.c (Fdefine_charset_internal): Likewise. * charset.h (struct charset.hash_index): Likewise. * composite.c (get_composition_id, gstring_lookup_cache): (composition_gstring_put_cache): Likewise. * composite.h (struct composition.hash_index): Likewise. * dispextern.h (struct image.hash): Likewise. * fns.c (next_almost_prime, larger_vector, cmpfn_eql): (cmpfn_equal, cmpfn_user_defined, hashfn_eq, hashfn_eql): (hashfn_equal, hashfn_user_defined, make_hash_table): (maybe_resize_hash_table, hash_lookup, hash_put): (hash_remove_from_table, hash_clear, sweep_weak_table, SXHASH_COMBINE): (sxhash_string, sxhash_list, sxhash_vector, sxhash_bool_vector): (Fsxhash, Fgethash, Fputhash, Fmaphash): Likewise. * image.c (make_image, search_image_cache, lookup_image): (xpm_put_color_table_h): Likewise. * lisp.h (struct Lisp_Hash_Table): Likewise, for 'count', 'cmpfn', and 'hashfn' members. * minibuf.c (Ftry_completion, Fall_completions, Ftest_completion): Likewise. * print.c (print): Likewise. * alloc.c (allocate_vectorlike): Check for overflow in vector size calculations. * ccl.c (ccl_driver): Check for overflow when converting EMACS_INT to int. * fns.c, image.c: Remove unnecessary static decls that would otherwise need to be updated by these changes. * fns.c (make_hash_table, maybe_resize_hash_table): Check for integer overflow with large hash tables. (make_hash_table, maybe_resize_hash_table, Fmake_hash_table): Prefer the faster XFLOAT_DATA to XFLOATINT where either will do. (SXHASH_REDUCE): New macro. (sxhash_string, sxhash_list, sxhash_vector, sxhash_bool_vector): Use it instead of discarding useful hash info with large hash values. (sxhash_float): New function. (sxhash): Use it. No more need for "& INTMASK" due to above changes. * lisp.h (FIXNUM_BITS): New macro, useful for SXHASH_REDUCE etc. (MOST_NEGATIVE_FIXNUM, MOST_POSITIVE_FIXNUM, INTMASK): Rewrite to use FIXNUM_BITS, as this simplifies things. (next_almost_prime, larger_vector, sxhash, hash_lookup, hash_put): Adjust signatures to match updated version of code. (consing_since_gc): Now EMACS_INT, since a single hash table can use more than INT_MAX bytes.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog49
-rw-r--r--src/alloc.c10
-rw-r--r--src/category.c4
-rw-r--r--src/ccl.c16
-rw-r--r--src/charset.c2
-rw-r--r--src/charset.h2
-rw-r--r--src/composite.c8
-rw-r--r--src/composite.h2
-rw-r--r--src/dispextern.h2
-rw-r--r--src/fns.c234
-rw-r--r--src/image.c10
-rw-r--r--src/lisp.h47
-rw-r--r--src/minibuf.c6
-rw-r--r--src/print.c2
14 files changed, 234 insertions, 160 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index fa8022b0d4d..029585b803f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,54 @@
12011-05-31 Paul Eggert <eggert@cs.ucla.edu> 12011-05-31 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 Remove arbitrary limit of 2**31 entries in hash tables.
4 * category.c (hash_get_category_set): Use 'EMACS_UINT' and 'EMACS_INT'
5 for hashes and hash indexes, instead of 'unsigned' and 'int'.
6 * ccl.c (ccl_driver): Likewise.
7 * charset.c (Fdefine_charset_internal): Likewise.
8 * charset.h (struct charset.hash_index): Likewise.
9 * composite.c (get_composition_id, gstring_lookup_cache):
10 (composition_gstring_put_cache): Likewise.
11 * composite.h (struct composition.hash_index): Likewise.
12 * dispextern.h (struct image.hash): Likewise.
13 * fns.c (next_almost_prime, larger_vector, cmpfn_eql):
14 (cmpfn_equal, cmpfn_user_defined, hashfn_eq, hashfn_eql):
15 (hashfn_equal, hashfn_user_defined, make_hash_table):
16 (maybe_resize_hash_table, hash_lookup, hash_put):
17 (hash_remove_from_table, hash_clear, sweep_weak_table, SXHASH_COMBINE):
18 (sxhash_string, sxhash_list, sxhash_vector, sxhash_bool_vector):
19 (Fsxhash, Fgethash, Fputhash, Fmaphash): Likewise.
20 * image.c (make_image, search_image_cache, lookup_image):
21 (xpm_put_color_table_h): Likewise.
22 * lisp.h (struct Lisp_Hash_Table): Likewise, for 'count', 'cmpfn',
23 and 'hashfn' members.
24 * minibuf.c (Ftry_completion, Fall_completions, Ftest_completion):
25 Likewise.
26 * print.c (print): Likewise.
27 * alloc.c (allocate_vectorlike): Check for overflow in vector size
28 calculations.
29 * ccl.c (ccl_driver): Check for overflow when converting EMACS_INT
30 to int.
31 * fns.c, image.c: Remove unnecessary static decls that would otherwise
32 need to be updated by these changes.
33 * fns.c (make_hash_table, maybe_resize_hash_table): Check for integer
34 overflow with large hash tables.
35 (make_hash_table, maybe_resize_hash_table, Fmake_hash_table):
36 Prefer the faster XFLOAT_DATA to XFLOATINT where either will do.
37 (SXHASH_REDUCE): New macro.
38 (sxhash_string, sxhash_list, sxhash_vector, sxhash_bool_vector):
39 Use it instead of discarding useful hash info with large hash values.
40 (sxhash_float): New function.
41 (sxhash): Use it. No more need for "& INTMASK" due to above changes.
42 * lisp.h (FIXNUM_BITS): New macro, useful for SXHASH_REDUCE etc.
43 (MOST_NEGATIVE_FIXNUM, MOST_POSITIVE_FIXNUM, INTMASK): Rewrite
44 to use FIXNUM_BITS, as this simplifies things.
45 (next_almost_prime, larger_vector, sxhash, hash_lookup, hash_put):
46 Adjust signatures to match updated version of code.
47 (consing_since_gc): Now EMACS_INT, since a single hash table can
48 use more than INT_MAX bytes.
49
502011-05-31 Paul Eggert <eggert@cs.ucla.edu>
51
3 Use 'inline', not 'INLINE'. 52 Use 'inline', not 'INLINE'.
4 <http://lists.gnu.org/archive/html/emacs-devel/2011-05/msg00914.html> 53 <http://lists.gnu.org/archive/html/emacs-devel/2011-05/msg00914.html>
5 * alloc.c, fontset.c (INLINE): Remove. 54 * alloc.c, fontset.c (INLINE): Remove.
diff --git a/src/alloc.c b/src/alloc.c
index e627af6c071..8fcc6f91df9 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -157,7 +157,7 @@ struct emacs_globals globals;
157 157
158/* Number of bytes of consing done since the last gc. */ 158/* Number of bytes of consing done since the last gc. */
159 159
160int consing_since_gc; 160EMACS_INT consing_since_gc;
161 161
162/* Similar minimum, computed from Vgc_cons_percentage. */ 162/* Similar minimum, computed from Vgc_cons_percentage. */
163 163
@@ -2788,6 +2788,11 @@ allocate_vectorlike (EMACS_INT len)
2788{ 2788{
2789 struct Lisp_Vector *p; 2789 struct Lisp_Vector *p;
2790 size_t nbytes; 2790 size_t nbytes;
2791 int header_size = offsetof (struct Lisp_Vector, contents);
2792 int word_size = sizeof p->contents[0];
2793
2794 if ((SIZE_MAX - header_size) / word_size < len)
2795 memory_full ();
2791 2796
2792 MALLOC_BLOCK_INPUT; 2797 MALLOC_BLOCK_INPUT;
2793 2798
@@ -2801,8 +2806,7 @@ allocate_vectorlike (EMACS_INT len)
2801 /* This gets triggered by code which I haven't bothered to fix. --Stef */ 2806 /* This gets triggered by code which I haven't bothered to fix. --Stef */
2802 /* eassert (!handling_signal); */ 2807 /* eassert (!handling_signal); */
2803 2808
2804 nbytes = (offsetof (struct Lisp_Vector, contents) 2809 nbytes = header_size + len * word_size;
2805 + len * sizeof p->contents[0]);
2806 p = (struct Lisp_Vector *) lisp_malloc (nbytes, MEM_TYPE_VECTORLIKE); 2810 p = (struct Lisp_Vector *) lisp_malloc (nbytes, MEM_TYPE_VECTORLIKE);
2807 2811
2808#ifdef DOUG_LEA_MALLOC 2812#ifdef DOUG_LEA_MALLOC
diff --git a/src/category.c b/src/category.c
index 356801a179c..23fd874c824 100644
--- a/src/category.c
+++ b/src/category.c
@@ -67,8 +67,8 @@ static Lisp_Object
67hash_get_category_set (Lisp_Object table, Lisp_Object category_set) 67hash_get_category_set (Lisp_Object table, Lisp_Object category_set)
68{ 68{
69 struct Lisp_Hash_Table *h; 69 struct Lisp_Hash_Table *h;
70 int i; 70 EMACS_INT i;
71 unsigned hash; 71 EMACS_UINT hash;
72 72
73 if (NILP (XCHAR_TABLE (table)->extras[1])) 73 if (NILP (XCHAR_TABLE (table)->extras[1]))
74 XCHAR_TABLE (table)->extras[1] 74 XCHAR_TABLE (table)->extras[1]
diff --git a/src/ccl.c b/src/ccl.c
index b04c74ccc25..e2ef4f194f3 100644
--- a/src/ccl.c
+++ b/src/ccl.c
@@ -1307,15 +1307,15 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1307 : -1)); 1307 : -1));
1308 h = GET_HASH_TABLE (eop); 1308 h = GET_HASH_TABLE (eop);
1309 1309
1310 op = hash_lookup (h, make_number (reg[RRR]), NULL); 1310 eop = hash_lookup (h, make_number (reg[RRR]), NULL);
1311 if (op >= 0) 1311 if (eop >= 0)
1312 { 1312 {
1313 Lisp_Object opl; 1313 Lisp_Object opl;
1314 opl = HASH_VALUE (h, op); 1314 opl = HASH_VALUE (h, eop);
1315 if (! CHARACTERP (opl)) 1315 if (! (IN_INT_RANGE (eop) && CHARACTERP (opl)))
1316 CCL_INVALID_CMD; 1316 CCL_INVALID_CMD;
1317 reg[RRR] = charset_unicode; 1317 reg[RRR] = charset_unicode;
1318 reg[rrr] = op; 1318 reg[rrr] = eop;
1319 reg[7] = 1; /* r7 true for success */ 1319 reg[7] = 1; /* r7 true for success */
1320 } 1320 }
1321 else 1321 else
@@ -1334,11 +1334,11 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1334 i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]); 1334 i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]);
1335 h = GET_HASH_TABLE (eop); 1335 h = GET_HASH_TABLE (eop);
1336 1336
1337 op = hash_lookup (h, make_number (i), NULL); 1337 eop = hash_lookup (h, make_number (i), NULL);
1338 if (op >= 0) 1338 if (eop >= 0)
1339 { 1339 {
1340 Lisp_Object opl; 1340 Lisp_Object opl;
1341 opl = HASH_VALUE (h, op); 1341 opl = HASH_VALUE (h, eop);
1342 if (! (INTEGERP (opl) && IN_INT_RANGE (XINT (opl)))) 1342 if (! (INTEGERP (opl) && IN_INT_RANGE (XINT (opl))))
1343 CCL_INVALID_CMD; 1343 CCL_INVALID_CMD;
1344 reg[RRR] = XINT (opl); 1344 reg[RRR] = XINT (opl);
diff --git a/src/charset.c b/src/charset.c
index b1b4993d277..0af21b48ad2 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -849,7 +849,7 @@ usage: (define-charset-internal ...) */)
849 /* Charset attr vector. */ 849 /* Charset attr vector. */
850 Lisp_Object attrs; 850 Lisp_Object attrs;
851 Lisp_Object val; 851 Lisp_Object val;
852 unsigned hash_code; 852 EMACS_UINT hash_code;
853 struct Lisp_Hash_Table *hash_table = XHASH_TABLE (Vcharset_hash_table); 853 struct Lisp_Hash_Table *hash_table = XHASH_TABLE (Vcharset_hash_table);
854 int i, j; 854 int i, j;
855 struct charset charset; 855 struct charset charset;
diff --git a/src/charset.h b/src/charset.h
index 53784bf8455..16f45ff9865 100644
--- a/src/charset.h
+++ b/src/charset.h
@@ -146,7 +146,7 @@ struct charset
146 int id; 146 int id;
147 147
148 /* Index to Vcharset_hash_table. */ 148 /* Index to Vcharset_hash_table. */
149 int hash_index; 149 EMACS_INT hash_index;
150 150
151 /* Dimension of the charset: 1, 2, 3, or 4. */ 151 /* Dimension of the charset: 1, 2, 3, or 4. */
152 int dimension; 152 int dimension;
diff --git a/src/composite.c b/src/composite.c
index 7849ffa3a18..ab9ec3f5a03 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -179,8 +179,8 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars,
179 Lisp_Object id, length, components, key, *key_contents; 179 Lisp_Object id, length, components, key, *key_contents;
180 int glyph_len; 180 int glyph_len;
181 struct Lisp_Hash_Table *hash_table = XHASH_TABLE (composition_hash_table); 181 struct Lisp_Hash_Table *hash_table = XHASH_TABLE (composition_hash_table);
182 int hash_index; 182 EMACS_INT hash_index;
183 unsigned hash_code; 183 EMACS_UINT hash_code;
184 struct composition *cmp; 184 struct composition *cmp;
185 EMACS_INT i; 185 EMACS_INT i;
186 int ch; 186 int ch;
@@ -656,7 +656,7 @@ static Lisp_Object
656gstring_lookup_cache (Lisp_Object header) 656gstring_lookup_cache (Lisp_Object header)
657{ 657{
658 struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table); 658 struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table);
659 int i = hash_lookup (h, header, NULL); 659 EMACS_INT i = hash_lookup (h, header, NULL);
660 660
661 return (i >= 0 ? HASH_VALUE (h, i) : Qnil); 661 return (i >= 0 ? HASH_VALUE (h, i) : Qnil);
662} 662}
@@ -665,7 +665,7 @@ Lisp_Object
665composition_gstring_put_cache (Lisp_Object gstring, EMACS_INT len) 665composition_gstring_put_cache (Lisp_Object gstring, EMACS_INT len)
666{ 666{
667 struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table); 667 struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table);
668 unsigned hash; 668 EMACS_UINT hash;
669 Lisp_Object header, copy; 669 Lisp_Object header, copy;
670 EMACS_INT i; 670 EMACS_INT i;
671 671
diff --git a/src/composite.h b/src/composite.h
index 5188f981d9c..cc8ca10a139 100644
--- a/src/composite.h
+++ b/src/composite.h
@@ -186,7 +186,7 @@ struct composition {
186 enum composition_method method; 186 enum composition_method method;
187 187
188 /* Index to the composition hash table. */ 188 /* Index to the composition hash table. */
189 int hash_index; 189 EMACS_INT hash_index;
190 190
191 /* For which font we have calculated the remaining members. The 191 /* For which font we have calculated the remaining members. The
192 actual type is device dependent. */ 192 actual type is device dependent. */
diff --git a/src/dispextern.h b/src/dispextern.h
index 5d8b4562499..e612a8b1eba 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2798,7 +2798,7 @@ struct image
2798 } data; 2798 } data;
2799 2799
2800 /* Hash value of image specification to speed up comparisons. */ 2800 /* Hash value of image specification to speed up comparisons. */
2801 unsigned hash; 2801 EMACS_UINT hash;
2802 2802
2803 /* Image id of this image. */ 2803 /* Image id of this image. */
2804 int id; 2804 int id;
diff --git a/src/fns.c b/src/fns.c
index 089f088b63d..4e22276a628 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -3358,21 +3358,6 @@ static Lisp_Object Qhash_table_test, Qkey_or_value, Qkey_and_value;
3358static struct Lisp_Hash_Table *check_hash_table (Lisp_Object); 3358static struct Lisp_Hash_Table *check_hash_table (Lisp_Object);
3359static size_t get_key_arg (Lisp_Object, size_t, Lisp_Object *, char *); 3359static size_t get_key_arg (Lisp_Object, size_t, Lisp_Object *, char *);
3360static void maybe_resize_hash_table (struct Lisp_Hash_Table *); 3360static void maybe_resize_hash_table (struct Lisp_Hash_Table *);
3361static int cmpfn_eql (struct Lisp_Hash_Table *, Lisp_Object, unsigned,
3362 Lisp_Object, unsigned);
3363static int cmpfn_equal (struct Lisp_Hash_Table *, Lisp_Object, unsigned,
3364 Lisp_Object, unsigned);
3365static int cmpfn_user_defined (struct Lisp_Hash_Table *, Lisp_Object,
3366 unsigned, Lisp_Object, unsigned);
3367static unsigned hashfn_eq (struct Lisp_Hash_Table *, Lisp_Object);
3368static unsigned hashfn_eql (struct Lisp_Hash_Table *, Lisp_Object);
3369static unsigned hashfn_equal (struct Lisp_Hash_Table *, Lisp_Object);
3370static unsigned hashfn_user_defined (struct Lisp_Hash_Table *,
3371 Lisp_Object);
3372static unsigned sxhash_string (unsigned char *, int);
3373static unsigned sxhash_list (Lisp_Object, int);
3374static unsigned sxhash_vector (Lisp_Object, int);
3375static unsigned sxhash_bool_vector (Lisp_Object);
3376static int sweep_weak_table (struct Lisp_Hash_Table *, int); 3361static int sweep_weak_table (struct Lisp_Hash_Table *, int);
3377 3362
3378 3363
@@ -3395,8 +3380,8 @@ check_hash_table (Lisp_Object obj)
3395/* Value is the next integer I >= N, N >= 0 which is "almost" a prime 3380/* Value is the next integer I >= N, N >= 0 which is "almost" a prime
3396 number. */ 3381 number. */
3397 3382
3398int 3383EMACS_INT
3399next_almost_prime (int n) 3384next_almost_prime (EMACS_INT n)
3400{ 3385{
3401 if (n % 2 == 0) 3386 if (n % 2 == 0)
3402 n += 1; 3387 n += 1;
@@ -3436,10 +3421,10 @@ get_key_arg (Lisp_Object key, size_t nargs, Lisp_Object *args, char *used)
3436 vector that are not copied from VEC are set to INIT. */ 3421 vector that are not copied from VEC are set to INIT. */
3437 3422
3438Lisp_Object 3423Lisp_Object
3439larger_vector (Lisp_Object vec, int new_size, Lisp_Object init) 3424larger_vector (Lisp_Object vec, EMACS_INT new_size, Lisp_Object init)
3440{ 3425{
3441 struct Lisp_Vector *v; 3426 struct Lisp_Vector *v;
3442 int i, old_size; 3427 EMACS_INT i, old_size;
3443 3428
3444 xassert (VECTORP (vec)); 3429 xassert (VECTORP (vec));
3445 old_size = ASIZE (vec); 3430 old_size = ASIZE (vec);
@@ -3463,7 +3448,9 @@ larger_vector (Lisp_Object vec, int new_size, Lisp_Object init)
3463 KEY2 are the same. */ 3448 KEY2 are the same. */
3464 3449
3465static int 3450static int
3466cmpfn_eql (struct Lisp_Hash_Table *h, Lisp_Object key1, unsigned int hash1, Lisp_Object key2, unsigned int hash2) 3451cmpfn_eql (struct Lisp_Hash_Table *h,
3452 Lisp_Object key1, EMACS_UINT hash1,
3453 Lisp_Object key2, EMACS_UINT hash2)
3467{ 3454{
3468 return (FLOATP (key1) 3455 return (FLOATP (key1)
3469 && FLOATP (key2) 3456 && FLOATP (key2)
@@ -3476,7 +3463,9 @@ cmpfn_eql (struct Lisp_Hash_Table *h, Lisp_Object key1, unsigned int hash1, Lisp
3476 KEY2 are the same. */ 3463 KEY2 are the same. */
3477 3464
3478static int 3465static int
3479cmpfn_equal (struct Lisp_Hash_Table *h, Lisp_Object key1, unsigned int hash1, Lisp_Object key2, unsigned int hash2) 3466cmpfn_equal (struct Lisp_Hash_Table *h,
3467 Lisp_Object key1, EMACS_UINT hash1,
3468 Lisp_Object key2, EMACS_UINT hash2)
3480{ 3469{
3481 return hash1 == hash2 && !NILP (Fequal (key1, key2)); 3470 return hash1 == hash2 && !NILP (Fequal (key1, key2));
3482} 3471}
@@ -3487,7 +3476,9 @@ cmpfn_equal (struct Lisp_Hash_Table *h, Lisp_Object key1, unsigned int hash1, Li
3487 if KEY1 and KEY2 are the same. */ 3476 if KEY1 and KEY2 are the same. */
3488 3477
3489static int 3478static int
3490cmpfn_user_defined (struct Lisp_Hash_Table *h, Lisp_Object key1, unsigned int hash1, Lisp_Object key2, unsigned int hash2) 3479cmpfn_user_defined (struct Lisp_Hash_Table *h,
3480 Lisp_Object key1, EMACS_UINT hash1,
3481 Lisp_Object key2, EMACS_UINT hash2)
3491{ 3482{
3492 if (hash1 == hash2) 3483 if (hash1 == hash2)
3493 { 3484 {
@@ -3507,10 +3498,10 @@ cmpfn_user_defined (struct Lisp_Hash_Table *h, Lisp_Object key1, unsigned int ha
3507 `eq' to compare keys. The hash code returned is guaranteed to fit 3498 `eq' to compare keys. The hash code returned is guaranteed to fit
3508 in a Lisp integer. */ 3499 in a Lisp integer. */
3509 3500
3510static unsigned 3501static EMACS_UINT
3511hashfn_eq (struct Lisp_Hash_Table *h, Lisp_Object key) 3502hashfn_eq (struct Lisp_Hash_Table *h, Lisp_Object key)
3512{ 3503{
3513 unsigned hash = XUINT (key) ^ XTYPE (key); 3504 EMACS_UINT hash = XUINT (key) ^ XTYPE (key);
3514 xassert ((hash & ~INTMASK) == 0); 3505 xassert ((hash & ~INTMASK) == 0);
3515 return hash; 3506 return hash;
3516} 3507}
@@ -3520,10 +3511,10 @@ hashfn_eq (struct Lisp_Hash_Table *h, Lisp_Object key)
3520 `eql' to compare keys. The hash code returned is guaranteed to fit 3511 `eql' to compare keys. The hash code returned is guaranteed to fit
3521 in a Lisp integer. */ 3512 in a Lisp integer. */
3522 3513
3523static unsigned 3514static EMACS_UINT
3524hashfn_eql (struct Lisp_Hash_Table *h, Lisp_Object key) 3515hashfn_eql (struct Lisp_Hash_Table *h, Lisp_Object key)
3525{ 3516{
3526 unsigned hash; 3517 EMACS_UINT hash;
3527 if (FLOATP (key)) 3518 if (FLOATP (key))
3528 hash = sxhash (key, 0); 3519 hash = sxhash (key, 0);
3529 else 3520 else
@@ -3537,10 +3528,10 @@ hashfn_eql (struct Lisp_Hash_Table *h, Lisp_Object key)
3537 `equal' to compare keys. The hash code returned is guaranteed to fit 3528 `equal' to compare keys. The hash code returned is guaranteed to fit
3538 in a Lisp integer. */ 3529 in a Lisp integer. */
3539 3530
3540static unsigned 3531static EMACS_UINT
3541hashfn_equal (struct Lisp_Hash_Table *h, Lisp_Object key) 3532hashfn_equal (struct Lisp_Hash_Table *h, Lisp_Object key)
3542{ 3533{
3543 unsigned hash = sxhash (key, 0); 3534 EMACS_UINT hash = sxhash (key, 0);
3544 xassert ((hash & ~INTMASK) == 0); 3535 xassert ((hash & ~INTMASK) == 0);
3545 return hash; 3536 return hash;
3546} 3537}
@@ -3550,7 +3541,7 @@ hashfn_equal (struct Lisp_Hash_Table *h, Lisp_Object key)
3550 user-defined function to compare keys. The hash code returned is 3541 user-defined function to compare keys. The hash code returned is
3551 guaranteed to fit in a Lisp integer. */ 3542 guaranteed to fit in a Lisp integer. */
3552 3543
3553static unsigned 3544static EMACS_UINT
3554hashfn_user_defined (struct Lisp_Hash_Table *h, Lisp_Object key) 3545hashfn_user_defined (struct Lisp_Hash_Table *h, Lisp_Object key)
3555{ 3546{
3556 Lisp_Object args[2], hash; 3547 Lisp_Object args[2], hash;
@@ -3593,26 +3584,33 @@ make_hash_table (Lisp_Object test, Lisp_Object size, Lisp_Object rehash_size,
3593{ 3584{
3594 struct Lisp_Hash_Table *h; 3585 struct Lisp_Hash_Table *h;
3595 Lisp_Object table; 3586 Lisp_Object table;
3596 int index_size, i, sz; 3587 EMACS_INT index_size, i, sz;
3588 double index_float;
3597 3589
3598 /* Preconditions. */ 3590 /* Preconditions. */
3599 xassert (SYMBOLP (test)); 3591 xassert (SYMBOLP (test));
3600 xassert (INTEGERP (size) && XINT (size) >= 0); 3592 xassert (INTEGERP (size) && XINT (size) >= 0);
3601 xassert ((INTEGERP (rehash_size) && XINT (rehash_size) > 0) 3593 xassert ((INTEGERP (rehash_size) && XINT (rehash_size) > 0)
3602 || (FLOATP (rehash_size) && XFLOATINT (rehash_size) > 1.0)); 3594 || (FLOATP (rehash_size) && 1 < XFLOAT_DATA (rehash_size)));
3603 xassert (FLOATP (rehash_threshold) 3595 xassert (FLOATP (rehash_threshold)
3604 && XFLOATINT (rehash_threshold) > 0 3596 && 0 < XFLOAT_DATA (rehash_threshold)
3605 && XFLOATINT (rehash_threshold) <= 1.0); 3597 && XFLOAT_DATA (rehash_threshold) <= 1.0);
3606 3598
3607 if (XFASTINT (size) == 0) 3599 if (XFASTINT (size) == 0)
3608 size = make_number (1); 3600 size = make_number (1);
3609 3601
3602 sz = XFASTINT (size);
3603 index_float = sz / XFLOAT_DATA (rehash_threshold);
3604 index_size = (index_float < MOST_POSITIVE_FIXNUM + 1
3605 ? next_almost_prime (index_float)
3606 : MOST_POSITIVE_FIXNUM + 1);
3607 if (MOST_POSITIVE_FIXNUM < max (index_size, 2 * sz))
3608 error ("Hash table too large");
3609
3610 /* Allocate a table and initialize it. */ 3610 /* Allocate a table and initialize it. */
3611 h = allocate_hash_table (); 3611 h = allocate_hash_table ();
3612 3612
3613 /* Initialize hash table slots. */ 3613 /* Initialize hash table slots. */
3614 sz = XFASTINT (size);
3615
3616 h->test = test; 3614 h->test = test;
3617 if (EQ (test, Qeql)) 3615 if (EQ (test, Qeql))
3618 { 3616 {
@@ -3644,8 +3642,6 @@ make_hash_table (Lisp_Object test, Lisp_Object size, Lisp_Object rehash_size,
3644 h->key_and_value = Fmake_vector (make_number (2 * sz), Qnil); 3642 h->key_and_value = Fmake_vector (make_number (2 * sz), Qnil);
3645 h->hash = Fmake_vector (size, Qnil); 3643 h->hash = Fmake_vector (size, Qnil);
3646 h->next = Fmake_vector (size, Qnil); 3644 h->next = Fmake_vector (size, Qnil);
3647 /* Cast to int here avoids losing with gcc 2.95 on Tru64/Alpha... */
3648 index_size = next_almost_prime ((int) (sz / XFLOATINT (rehash_threshold)));
3649 h->index = Fmake_vector (make_number (index_size), Qnil); 3645 h->index = Fmake_vector (make_number (index_size), Qnil);
3650 3646
3651 /* Set up the free list. */ 3647 /* Set up the free list. */
@@ -3709,20 +3705,29 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
3709{ 3705{
3710 if (NILP (h->next_free)) 3706 if (NILP (h->next_free))
3711 { 3707 {
3712 int old_size = HASH_TABLE_SIZE (h); 3708 EMACS_INT old_size = HASH_TABLE_SIZE (h);
3713 int i, new_size, index_size; 3709 EMACS_INT i, new_size, index_size;
3714 EMACS_INT nsize; 3710 EMACS_INT nsize;
3711 double index_float;
3715 3712
3716 if (INTEGERP (h->rehash_size)) 3713 if (INTEGERP (h->rehash_size))
3717 new_size = old_size + XFASTINT (h->rehash_size); 3714 new_size = old_size + XFASTINT (h->rehash_size);
3718 else 3715 else
3719 new_size = old_size * XFLOATINT (h->rehash_size); 3716 {
3720 new_size = max (old_size + 1, new_size); 3717 double float_new_size = old_size * XFLOAT_DATA (h->rehash_size);
3721 index_size = next_almost_prime ((int) 3718 if (float_new_size < MOST_POSITIVE_FIXNUM + 1)
3722 (new_size 3719 {
3723 / XFLOATINT (h->rehash_threshold))); 3720 new_size = float_new_size;
3724 /* Assignment to EMACS_INT stops GCC whining about limited range 3721 if (new_size <= old_size)
3725 of data type. */ 3722 new_size = old_size + 1;
3723 }
3724 else
3725 new_size = MOST_POSITIVE_FIXNUM + 1;
3726 }
3727 index_float = new_size / XFLOAT_DATA (h->rehash_threshold);
3728 index_size = (index_float < MOST_POSITIVE_FIXNUM + 1
3729 ? next_almost_prime (index_float)
3730 : MOST_POSITIVE_FIXNUM + 1);
3726 nsize = max (index_size, 2 * new_size); 3731 nsize = max (index_size, 2 * new_size);
3727 if (nsize > MOST_POSITIVE_FIXNUM) 3732 if (nsize > MOST_POSITIVE_FIXNUM)
3728 error ("Hash table too large to resize"); 3733 error ("Hash table too large to resize");
@@ -3756,8 +3761,8 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
3756 for (i = 0; i < old_size; ++i) 3761 for (i = 0; i < old_size; ++i)
3757 if (!NILP (HASH_HASH (h, i))) 3762 if (!NILP (HASH_HASH (h, i)))
3758 { 3763 {
3759 unsigned hash_code = XUINT (HASH_HASH (h, i)); 3764 EMACS_UINT hash_code = XUINT (HASH_HASH (h, i));
3760 int start_of_bucket = hash_code % ASIZE (h->index); 3765 EMACS_INT start_of_bucket = hash_code % ASIZE (h->index);
3761 HASH_NEXT (h, i) = HASH_INDEX (h, start_of_bucket); 3766 HASH_NEXT (h, i) = HASH_INDEX (h, start_of_bucket);
3762 HASH_INDEX (h, start_of_bucket) = make_number (i); 3767 HASH_INDEX (h, start_of_bucket) = make_number (i);
3763 } 3768 }
@@ -3769,11 +3774,11 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
3769 the hash code of KEY. Value is the index of the entry in H 3774 the hash code of KEY. Value is the index of the entry in H
3770 matching KEY, or -1 if not found. */ 3775 matching KEY, or -1 if not found. */
3771 3776
3772int 3777EMACS_INT
3773hash_lookup (struct Lisp_Hash_Table *h, Lisp_Object key, unsigned int *hash) 3778hash_lookup (struct Lisp_Hash_Table *h, Lisp_Object key, EMACS_UINT *hash)
3774{ 3779{
3775 unsigned hash_code; 3780 EMACS_UINT hash_code;
3776 int start_of_bucket; 3781 EMACS_INT start_of_bucket;
3777 Lisp_Object idx; 3782 Lisp_Object idx;
3778 3783
3779 hash_code = h->hashfn (h, key); 3784 hash_code = h->hashfn (h, key);
@@ -3786,7 +3791,7 @@ hash_lookup (struct Lisp_Hash_Table *h, Lisp_Object key, unsigned int *hash)
3786 /* We need not gcpro idx since it's either an integer or nil. */ 3791 /* We need not gcpro idx since it's either an integer or nil. */
3787 while (!NILP (idx)) 3792 while (!NILP (idx))
3788 { 3793 {
3789 int i = XFASTINT (idx); 3794 EMACS_INT i = XFASTINT (idx);
3790 if (EQ (key, HASH_KEY (h, i)) 3795 if (EQ (key, HASH_KEY (h, i))
3791 || (h->cmpfn 3796 || (h->cmpfn
3792 && h->cmpfn (h, key, hash_code, 3797 && h->cmpfn (h, key, hash_code,
@@ -3803,10 +3808,11 @@ hash_lookup (struct Lisp_Hash_Table *h, Lisp_Object key, unsigned int *hash)
3803 HASH is a previously computed hash code of KEY. 3808 HASH is a previously computed hash code of KEY.
3804 Value is the index of the entry in H matching KEY. */ 3809 Value is the index of the entry in H matching KEY. */
3805 3810
3806int 3811EMACS_INT
3807hash_put (struct Lisp_Hash_Table *h, Lisp_Object key, Lisp_Object value, unsigned int hash) 3812hash_put (struct Lisp_Hash_Table *h, Lisp_Object key, Lisp_Object value,
3813 EMACS_UINT hash)
3808{ 3814{
3809 int start_of_bucket, i; 3815 EMACS_INT start_of_bucket, i;
3810 3816
3811 xassert ((hash & ~INTMASK) == 0); 3817 xassert ((hash & ~INTMASK) == 0);
3812 3818
@@ -3836,8 +3842,8 @@ hash_put (struct Lisp_Hash_Table *h, Lisp_Object key, Lisp_Object value, unsigne
3836static void 3842static void
3837hash_remove_from_table (struct Lisp_Hash_Table *h, Lisp_Object key) 3843hash_remove_from_table (struct Lisp_Hash_Table *h, Lisp_Object key)
3838{ 3844{
3839 unsigned hash_code; 3845 EMACS_UINT hash_code;
3840 int start_of_bucket; 3846 EMACS_INT start_of_bucket;
3841 Lisp_Object idx, prev; 3847 Lisp_Object idx, prev;
3842 3848
3843 hash_code = h->hashfn (h, key); 3849 hash_code = h->hashfn (h, key);
@@ -3848,7 +3854,7 @@ hash_remove_from_table (struct Lisp_Hash_Table *h, Lisp_Object key)
3848 /* We need not gcpro idx, prev since they're either integers or nil. */ 3854 /* We need not gcpro idx, prev since they're either integers or nil. */
3849 while (!NILP (idx)) 3855 while (!NILP (idx))
3850 { 3856 {
3851 int i = XFASTINT (idx); 3857 EMACS_INT i = XFASTINT (idx);
3852 3858
3853 if (EQ (key, HASH_KEY (h, i)) 3859 if (EQ (key, HASH_KEY (h, i))
3854 || (h->cmpfn 3860 || (h->cmpfn
@@ -3886,7 +3892,7 @@ hash_clear (struct Lisp_Hash_Table *h)
3886{ 3892{
3887 if (h->count > 0) 3893 if (h->count > 0)
3888 { 3894 {
3889 int i, size = HASH_TABLE_SIZE (h); 3895 EMACS_INT i, size = HASH_TABLE_SIZE (h);
3890 3896
3891 for (i = 0; i < size; ++i) 3897 for (i = 0; i < size; ++i)
3892 { 3898 {
@@ -3924,7 +3930,8 @@ init_weak_hash_tables (void)
3924static int 3930static int
3925sweep_weak_table (struct Lisp_Hash_Table *h, int remove_entries_p) 3931sweep_weak_table (struct Lisp_Hash_Table *h, int remove_entries_p)
3926{ 3932{
3927 int bucket, n, marked; 3933 EMACS_INT bucket, n;
3934 int marked;
3928 3935
3929 n = ASIZE (h->index) & ~ARRAY_MARK_FLAG; 3936 n = ASIZE (h->index) & ~ARRAY_MARK_FLAG;
3930 marked = 0; 3937 marked = 0;
@@ -3938,7 +3945,7 @@ sweep_weak_table (struct Lisp_Hash_Table *h, int remove_entries_p)
3938 prev = Qnil; 3945 prev = Qnil;
3939 for (idx = HASH_INDEX (h, bucket); !NILP (idx); idx = next) 3946 for (idx = HASH_INDEX (h, bucket); !NILP (idx); idx = next)
3940 { 3947 {
3941 int i = XFASTINT (idx); 3948 EMACS_INT i = XFASTINT (idx);
3942 int key_known_to_survive_p = survives_gc_p (HASH_KEY (h, i)); 3949 int key_known_to_survive_p = survives_gc_p (HASH_KEY (h, i));
3943 int value_known_to_survive_p = survives_gc_p (HASH_VALUE (h, i)); 3950 int value_known_to_survive_p = survives_gc_p (HASH_VALUE (h, i));
3944 int remove_p; 3951 int remove_p;
@@ -4067,43 +4074,68 @@ sweep_weak_hash_tables (void)
4067 4074
4068#define SXHASH_MAX_LEN 7 4075#define SXHASH_MAX_LEN 7
4069 4076
4070/* Combine two integers X and Y for hashing. */ 4077/* Combine two integers X and Y for hashing. The result might not fit
4078 into a Lisp integer. */
4071 4079
4072#define SXHASH_COMBINE(X, Y) \ 4080#define SXHASH_COMBINE(X, Y) \
4073 ((((unsigned)(X) << 4) + (((unsigned)(X) >> 24) & 0x0fffffff)) \ 4081 ((((EMACS_UINT) (X) << 4) + ((EMACS_UINT) (X) >> (BITS_PER_EMACS_INT - 4))) \
4074 + (unsigned)(Y)) 4082 + (EMACS_UINT) (Y))
4075 4083
4084/* Hash X, returning a value that fits into a Lisp integer. */
4085#define SXHASH_REDUCE(X) \
4086 ((((X) ^ (X) >> (BITS_PER_EMACS_INT - FIXNUM_BITS))) & INTMASK)
4076 4087
4077/* Return a hash for string PTR which has length LEN. The hash 4088/* Return a hash for string PTR which has length LEN. The hash
4078 code returned is guaranteed to fit in a Lisp integer. */ 4089 code returned is guaranteed to fit in a Lisp integer. */
4079 4090
4080static unsigned 4091static EMACS_UINT
4081sxhash_string (unsigned char *ptr, int len) 4092sxhash_string (unsigned char *ptr, EMACS_INT len)
4082{ 4093{
4083 unsigned char *p = ptr; 4094 unsigned char *p = ptr;
4084 unsigned char *end = p + len; 4095 unsigned char *end = p + len;
4085 unsigned char c; 4096 unsigned char c;
4086 unsigned hash = 0; 4097 EMACS_UINT hash = 0;
4087 4098
4088 while (p != end) 4099 while (p != end)
4089 { 4100 {
4090 c = *p++; 4101 c = *p++;
4091 if (c >= 0140) 4102 if (c >= 0140)
4092 c -= 40; 4103 c -= 40;
4093 hash = ((hash << 4) + (hash >> 28) + c); 4104 hash = SXHASH_COMBINE (hash, c);
4094 } 4105 }
4095 4106
4096 return hash & INTMASK; 4107 return SXHASH_REDUCE (hash);
4097} 4108}
4098 4109
4110/* Return a hash for the floating point value VAL. */
4111
4112static EMACS_INT
4113sxhash_float (double val)
4114{
4115 EMACS_UINT hash = 0;
4116 enum {
4117 WORDS_PER_DOUBLE = (sizeof val / sizeof hash
4118 + (sizeof val % sizeof hash != 0))
4119 };
4120 union {
4121 double val;
4122 EMACS_UINT word[WORDS_PER_DOUBLE];
4123 } u;
4124 int i;
4125 u.val = val;
4126 memset (&u.val + 1, 0, sizeof u - sizeof u.val);
4127 for (i = 0; i < WORDS_PER_DOUBLE; i++)
4128 hash = SXHASH_COMBINE (hash, u.word[i]);
4129 return SXHASH_REDUCE (hash);
4130}
4099 4131
4100/* Return a hash for list LIST. DEPTH is the current depth in the 4132/* Return a hash for list LIST. DEPTH is the current depth in the
4101 list. We don't recurse deeper than SXHASH_MAX_DEPTH in it. */ 4133 list. We don't recurse deeper than SXHASH_MAX_DEPTH in it. */
4102 4134
4103static unsigned 4135static EMACS_UINT
4104sxhash_list (Lisp_Object list, int depth) 4136sxhash_list (Lisp_Object list, int depth)
4105{ 4137{
4106 unsigned hash = 0; 4138 EMACS_UINT hash = 0;
4107 int i; 4139 int i;
4108 4140
4109 if (depth < SXHASH_MAX_DEPTH) 4141 if (depth < SXHASH_MAX_DEPTH)
@@ -4111,63 +4143,62 @@ sxhash_list (Lisp_Object list, int depth)
4111 CONSP (list) && i < SXHASH_MAX_LEN; 4143 CONSP (list) && i < SXHASH_MAX_LEN;
4112 list = XCDR (list), ++i) 4144 list = XCDR (list), ++i)
4113 { 4145 {
4114 unsigned hash2 = sxhash (XCAR (list), depth + 1); 4146 EMACS_UINT hash2 = sxhash (XCAR (list), depth + 1);
4115 hash = SXHASH_COMBINE (hash, hash2); 4147 hash = SXHASH_COMBINE (hash, hash2);
4116 } 4148 }
4117 4149
4118 if (!NILP (list)) 4150 if (!NILP (list))
4119 { 4151 {
4120 unsigned hash2 = sxhash (list, depth + 1); 4152 EMACS_UINT hash2 = sxhash (list, depth + 1);
4121 hash = SXHASH_COMBINE (hash, hash2); 4153 hash = SXHASH_COMBINE (hash, hash2);
4122 } 4154 }
4123 4155
4124 return hash; 4156 return SXHASH_REDUCE (hash);
4125} 4157}
4126 4158
4127 4159
4128/* Return a hash for vector VECTOR. DEPTH is the current depth in 4160/* Return a hash for vector VECTOR. DEPTH is the current depth in
4129 the Lisp structure. */ 4161 the Lisp structure. */
4130 4162
4131static unsigned 4163static EMACS_UINT
4132sxhash_vector (Lisp_Object vec, int depth) 4164sxhash_vector (Lisp_Object vec, int depth)
4133{ 4165{
4134 unsigned hash = ASIZE (vec); 4166 EMACS_UINT hash = ASIZE (vec);
4135 int i, n; 4167 int i, n;
4136 4168
4137 n = min (SXHASH_MAX_LEN, ASIZE (vec)); 4169 n = min (SXHASH_MAX_LEN, ASIZE (vec));
4138 for (i = 0; i < n; ++i) 4170 for (i = 0; i < n; ++i)
4139 { 4171 {
4140 unsigned hash2 = sxhash (AREF (vec, i), depth + 1); 4172 EMACS_UINT hash2 = sxhash (AREF (vec, i), depth + 1);
4141 hash = SXHASH_COMBINE (hash, hash2); 4173 hash = SXHASH_COMBINE (hash, hash2);
4142 } 4174 }
4143 4175
4144 return hash; 4176 return SXHASH_REDUCE (hash);
4145} 4177}
4146 4178
4147
4148/* Return a hash for bool-vector VECTOR. */ 4179/* Return a hash for bool-vector VECTOR. */
4149 4180
4150static unsigned 4181static EMACS_UINT
4151sxhash_bool_vector (Lisp_Object vec) 4182sxhash_bool_vector (Lisp_Object vec)
4152{ 4183{
4153 unsigned hash = XBOOL_VECTOR (vec)->size; 4184 EMACS_UINT hash = XBOOL_VECTOR (vec)->size;
4154 int i, n; 4185 int i, n;
4155 4186
4156 n = min (SXHASH_MAX_LEN, XBOOL_VECTOR (vec)->header.size); 4187 n = min (SXHASH_MAX_LEN, XBOOL_VECTOR (vec)->header.size);
4157 for (i = 0; i < n; ++i) 4188 for (i = 0; i < n; ++i)
4158 hash = SXHASH_COMBINE (hash, XBOOL_VECTOR (vec)->data[i]); 4189 hash = SXHASH_COMBINE (hash, XBOOL_VECTOR (vec)->data[i]);
4159 4190
4160 return hash; 4191 return SXHASH_REDUCE (hash);
4161} 4192}
4162 4193
4163 4194
4164/* Return a hash code for OBJ. DEPTH is the current depth in the Lisp 4195/* Return a hash code for OBJ. DEPTH is the current depth in the Lisp
4165 structure. Value is an unsigned integer clipped to INTMASK. */ 4196 structure. Value is an unsigned integer clipped to INTMASK. */
4166 4197
4167unsigned 4198EMACS_UINT
4168sxhash (Lisp_Object obj, int depth) 4199sxhash (Lisp_Object obj, int depth)
4169{ 4200{
4170 unsigned hash; 4201 EMACS_UINT hash;
4171 4202
4172 if (depth > SXHASH_MAX_DEPTH) 4203 if (depth > SXHASH_MAX_DEPTH)
4173 return 0; 4204 return 0;
@@ -4211,20 +4242,14 @@ sxhash (Lisp_Object obj, int depth)
4211 break; 4242 break;
4212 4243
4213 case Lisp_Float: 4244 case Lisp_Float:
4214 { 4245 hash = sxhash_float (XFLOAT_DATA (obj));
4215 double val = XFLOAT_DATA (obj); 4246 break;
4216 unsigned char *p = (unsigned char *) &val;
4217 size_t i;
4218 for (hash = 0, i = 0; i < sizeof val; i++)
4219 hash = SXHASH_COMBINE (hash, p[i]);
4220 break;
4221 }
4222 4247
4223 default: 4248 default:
4224 abort (); 4249 abort ();
4225 } 4250 }
4226 4251
4227 return hash & INTMASK; 4252 return hash;
4228} 4253}
4229 4254
4230 4255
@@ -4238,7 +4263,7 @@ DEFUN ("sxhash", Fsxhash, Ssxhash, 1, 1, 0,
4238 doc: /* Compute a hash code for OBJ and return it as integer. */) 4263 doc: /* Compute a hash code for OBJ and return it as integer. */)
4239 (Lisp_Object obj) 4264 (Lisp_Object obj)
4240{ 4265{
4241 unsigned hash = sxhash (obj, 0); 4266 EMACS_UINT hash = sxhash (obj, 0);
4242 return make_number (hash); 4267 return make_number (hash);
4243} 4268}
4244 4269
@@ -4315,17 +4340,16 @@ usage: (make-hash-table &rest KEYWORD-ARGS) */)
4315 /* Look for `:rehash-size SIZE'. */ 4340 /* Look for `:rehash-size SIZE'. */
4316 i = get_key_arg (QCrehash_size, nargs, args, used); 4341 i = get_key_arg (QCrehash_size, nargs, args, used);
4317 rehash_size = i ? args[i] : make_float (DEFAULT_REHASH_SIZE); 4342 rehash_size = i ? args[i] : make_float (DEFAULT_REHASH_SIZE);
4318 if (!NUMBERP (rehash_size) 4343 if (! ((INTEGERP (rehash_size) && 0 < XINT (rehash_size))
4319 || (INTEGERP (rehash_size) && XINT (rehash_size) <= 0) 4344 || (FLOATP (rehash_size) && 1 < XFLOAT_DATA (rehash_size))))
4320 || XFLOATINT (rehash_size) <= 1.0)
4321 signal_error ("Invalid hash table rehash size", rehash_size); 4345 signal_error ("Invalid hash table rehash size", rehash_size);
4322 4346
4323 /* Look for `:rehash-threshold THRESHOLD'. */ 4347 /* Look for `:rehash-threshold THRESHOLD'. */
4324 i = get_key_arg (QCrehash_threshold, nargs, args, used); 4348 i = get_key_arg (QCrehash_threshold, nargs, args, used);
4325 rehash_threshold = i ? args[i] : make_float (DEFAULT_REHASH_THRESHOLD); 4349 rehash_threshold = i ? args[i] : make_float (DEFAULT_REHASH_THRESHOLD);
4326 if (!FLOATP (rehash_threshold) 4350 if (! (FLOATP (rehash_threshold)
4327 || XFLOATINT (rehash_threshold) <= 0.0 4351 && 0 < XFLOAT_DATA (rehash_threshold)
4328 || XFLOATINT (rehash_threshold) > 1.0) 4352 && XFLOAT_DATA (rehash_threshold) <= 1))
4329 signal_error ("Invalid hash table rehash threshold", rehash_threshold); 4353 signal_error ("Invalid hash table rehash threshold", rehash_threshold);
4330 4354
4331 /* Look for `:weakness WEAK'. */ 4355 /* Look for `:weakness WEAK'. */
@@ -4437,7 +4461,7 @@ If KEY is not found, return DFLT which defaults to nil. */)
4437 (Lisp_Object key, Lisp_Object table, Lisp_Object dflt) 4461 (Lisp_Object key, Lisp_Object table, Lisp_Object dflt)
4438{ 4462{
4439 struct Lisp_Hash_Table *h = check_hash_table (table); 4463 struct Lisp_Hash_Table *h = check_hash_table (table);
4440 int i = hash_lookup (h, key, NULL); 4464 EMACS_INT i = hash_lookup (h, key, NULL);
4441 return i >= 0 ? HASH_VALUE (h, i) : dflt; 4465 return i >= 0 ? HASH_VALUE (h, i) : dflt;
4442} 4466}
4443 4467
@@ -4449,8 +4473,8 @@ VALUE. */)
4449 (Lisp_Object key, Lisp_Object value, Lisp_Object table) 4473 (Lisp_Object key, Lisp_Object value, Lisp_Object table)
4450{ 4474{
4451 struct Lisp_Hash_Table *h = check_hash_table (table); 4475 struct Lisp_Hash_Table *h = check_hash_table (table);
4452 int i; 4476 EMACS_INT i;
4453 unsigned hash; 4477 EMACS_UINT hash;
4454 4478
4455 i = hash_lookup (h, key, &hash); 4479 i = hash_lookup (h, key, &hash);
4456 if (i >= 0) 4480 if (i >= 0)
@@ -4479,7 +4503,7 @@ FUNCTION is called with two arguments, KEY and VALUE. */)
4479{ 4503{
4480 struct Lisp_Hash_Table *h = check_hash_table (table); 4504 struct Lisp_Hash_Table *h = check_hash_table (table);
4481 Lisp_Object args[3]; 4505 Lisp_Object args[3];
4482 int i; 4506 EMACS_INT i;
4483 4507
4484 for (i = 0; i < HASH_TABLE_SIZE (h); ++i) 4508 for (i = 0; i < HASH_TABLE_SIZE (h); ++i)
4485 if (!NILP (HASH_HASH (h, i))) 4509 if (!NILP (HASH_HASH (h, i)))
diff --git a/src/image.c b/src/image.c
index 0f269f46492..26542bf27e7 100644
--- a/src/image.c
+++ b/src/image.c
@@ -982,7 +982,6 @@ or omitted means use the selected frame. */)
982 Image type independent image structures 982 Image type independent image structures
983 ***********************************************************************/ 983 ***********************************************************************/
984 984
985static struct image *make_image (Lisp_Object spec, unsigned hash);
986static void free_image (struct frame *f, struct image *img); 985static void free_image (struct frame *f, struct image *img);
987static int check_image_size (struct frame *f, int width, int height); 986static int check_image_size (struct frame *f, int width, int height);
988 987
@@ -991,7 +990,7 @@ static int check_image_size (struct frame *f, int width, int height);
991 SPEC. SPEC has a hash value of HASH. */ 990 SPEC. SPEC has a hash value of HASH. */
992 991
993static struct image * 992static struct image *
994make_image (Lisp_Object spec, unsigned int hash) 993make_image (Lisp_Object spec, EMACS_UINT hash)
995{ 994{
996 struct image *img = (struct image *) xmalloc (sizeof *img); 995 struct image *img = (struct image *) xmalloc (sizeof *img);
997 Lisp_Object file = image_spec_value (spec, QCfile, NULL); 996 Lisp_Object file = image_spec_value (spec, QCfile, NULL);
@@ -1388,7 +1387,6 @@ x_alloc_image_color (struct frame *f, struct image *img, Lisp_Object color_name,
1388 Image Cache 1387 Image Cache
1389 ***********************************************************************/ 1388 ***********************************************************************/
1390 1389
1391static struct image *search_image_cache (struct frame *, Lisp_Object, unsigned);
1392static void cache_image (struct frame *f, struct image *img); 1390static void cache_image (struct frame *f, struct image *img);
1393static void postprocess_image (struct frame *, struct image *); 1391static void postprocess_image (struct frame *, struct image *);
1394 1392
@@ -1414,7 +1412,7 @@ make_image_cache (void)
1414/* Find an image matching SPEC in the cache, and return it. If no 1412/* Find an image matching SPEC in the cache, and return it. If no
1415 image is found, return NULL. */ 1413 image is found, return NULL. */
1416static struct image * 1414static struct image *
1417search_image_cache (struct frame *f, Lisp_Object spec, unsigned int hash) 1415search_image_cache (struct frame *f, Lisp_Object spec, EMACS_UINT hash)
1418{ 1416{
1419 struct image *img; 1417 struct image *img;
1420 struct image_cache *c = FRAME_IMAGE_CACHE (f); 1418 struct image_cache *c = FRAME_IMAGE_CACHE (f);
@@ -1714,7 +1712,7 @@ int
1714lookup_image (struct frame *f, Lisp_Object spec) 1712lookup_image (struct frame *f, Lisp_Object spec)
1715{ 1713{
1716 struct image *img; 1714 struct image *img;
1717 unsigned hash; 1715 EMACS_UINT hash;
1718 EMACS_TIME now; 1716 EMACS_TIME now;
1719 1717
1720 /* F must be a window-system frame, and SPEC must be a valid image 1718 /* F must be a window-system frame, and SPEC must be a valid image
@@ -3751,7 +3749,7 @@ xpm_put_color_table_h (Lisp_Object color_table,
3751 Lisp_Object color) 3749 Lisp_Object color)
3752{ 3750{
3753 struct Lisp_Hash_Table *table = XHASH_TABLE (color_table); 3751 struct Lisp_Hash_Table *table = XHASH_TABLE (color_table);
3754 unsigned hash_code; 3752 EMACS_UINT hash_code;
3755 Lisp_Object chars = make_unibyte_string (chars_start, chars_len); 3753 Lisp_Object chars = make_unibyte_string (chars_start, chars_len);
3756 3754
3757 hash_lookup (table, chars, &hash_code); 3755 hash_lookup (table, chars, &hash_code);
diff --git a/src/lisp.h b/src/lisp.h
index 8a504e8eb86..6e61d0b8bd3 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -525,23 +525,21 @@ extern Lisp_Object make_number (EMACS_INT);
525 525
526#define EQ(x, y) (XHASH (x) == XHASH (y)) 526#define EQ(x, y) (XHASH (x) == XHASH (y))
527 527
528/* Largest and smallest representable fixnum values. These are the C 528/* Number of bits in a fixnum, including the sign bit. */
529 values. */
530
531#ifdef USE_2_TAGS_FOR_INTS 529#ifdef USE_2_TAGS_FOR_INTS
532# define MOST_NEGATIVE_FIXNUM - ((EMACS_INT) 1 << VALBITS) 530# define FIXNUM_BITS (VALBITS + 1)
533# define MOST_POSITIVE_FIXNUM (((EMACS_INT) 1 << VALBITS) - 1)
534/* Mask indicating the significant bits of a Lisp_Int.
535 I.e. (x & INTMASK) == XUINT (make_number (x)). */
536# define INTMASK ((((EMACS_INT) 1) << (VALBITS + 1)) - 1)
537#else 531#else
538# define MOST_NEGATIVE_FIXNUM - ((EMACS_INT) 1 << (VALBITS - 1)) 532# define FIXNUM_BITS VALBITS
539# define MOST_POSITIVE_FIXNUM (((EMACS_INT) 1 << (VALBITS - 1)) - 1)
540/* Mask indicating the significant bits of a Lisp_Int.
541 I.e. (x & INTMASK) == XUINT (make_number (x)). */
542# define INTMASK ((((EMACS_INT) 1) << VALBITS) - 1)
543#endif 533#endif
544 534
535/* Mask indicating the significant bits of a fixnum. */
536#define INTMASK (((EMACS_INT) 1 << FIXNUM_BITS) - 1)
537
538/* Largest and smallest representable fixnum values. These are the C
539 values. */
540#define MOST_POSITIVE_FIXNUM (INTMASK / 2)
541#define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM)
542
545/* Value is non-zero if I doesn't fit into a Lisp fixnum. It is 543/* Value is non-zero if I doesn't fit into a Lisp fixnum. It is
546 written this way so that it also works if I is of unsigned 544 written this way so that it also works if I is of unsigned
547 type or if I is a NaN. */ 545 type or if I is a NaN. */
@@ -1179,7 +1177,7 @@ struct Lisp_Hash_Table
1179 a special way (e.g. because of weakness). */ 1177 a special way (e.g. because of weakness). */
1180 1178
1181 /* Number of key/value entries in the table. */ 1179 /* Number of key/value entries in the table. */
1182 unsigned int count; 1180 EMACS_INT count;
1183 1181
1184 /* Vector of keys and values. The key of item I is found at index 1182 /* Vector of keys and values. The key of item I is found at index
1185 2 * I, the value is found at index 2 * I + 1. 1183 2 * I, the value is found at index 2 * I + 1.
@@ -1191,11 +1189,12 @@ struct Lisp_Hash_Table
1191 struct Lisp_Hash_Table *next_weak; 1189 struct Lisp_Hash_Table *next_weak;
1192 1190
1193 /* C function to compare two keys. */ 1191 /* C function to compare two keys. */
1194 int (* cmpfn) (struct Lisp_Hash_Table *, Lisp_Object, 1192 int (*cmpfn) (struct Lisp_Hash_Table *,
1195 unsigned, Lisp_Object, unsigned); 1193 Lisp_Object, EMACS_UINT,
1194 Lisp_Object, EMACS_UINT);
1196 1195
1197 /* C function to compute hash code. */ 1196 /* C function to compute hash code. */
1198 unsigned (* hashfn) (struct Lisp_Hash_Table *, Lisp_Object); 1197 EMACS_UINT (*hashfn) (struct Lisp_Hash_Table *, Lisp_Object);
1199}; 1198};
1200 1199
1201 1200
@@ -2093,7 +2092,7 @@ extern Lisp_Object Vascii_canon_table;
2093 2092
2094/* Number of bytes of structure consed since last GC. */ 2093/* Number of bytes of structure consed since last GC. */
2095 2094
2096extern int consing_since_gc; 2095extern EMACS_INT consing_since_gc;
2097 2096
2098extern EMACS_INT gc_relative_threshold; 2097extern EMACS_INT gc_relative_threshold;
2099 2098
@@ -2468,19 +2467,19 @@ extern void syms_of_syntax (void);
2468 2467
2469/* Defined in fns.c */ 2468/* Defined in fns.c */
2470extern Lisp_Object QCrehash_size, QCrehash_threshold; 2469extern Lisp_Object QCrehash_size, QCrehash_threshold;
2471extern int next_almost_prime (int); 2470extern EMACS_INT next_almost_prime (EMACS_INT);
2472extern Lisp_Object larger_vector (Lisp_Object, int, Lisp_Object); 2471extern Lisp_Object larger_vector (Lisp_Object, EMACS_INT, Lisp_Object);
2473extern void sweep_weak_hash_tables (void); 2472extern void sweep_weak_hash_tables (void);
2474extern Lisp_Object Qcursor_in_echo_area; 2473extern Lisp_Object Qcursor_in_echo_area;
2475extern Lisp_Object Qstring_lessp; 2474extern Lisp_Object Qstring_lessp;
2476extern Lisp_Object QCsize, QCtest, QCweakness, Qequal, Qeq, Qeql; 2475extern Lisp_Object QCsize, QCtest, QCweakness, Qequal, Qeq, Qeql;
2477unsigned sxhash (Lisp_Object, int); 2476EMACS_UINT sxhash (Lisp_Object, int);
2478Lisp_Object make_hash_table (Lisp_Object, Lisp_Object, Lisp_Object, 2477Lisp_Object make_hash_table (Lisp_Object, Lisp_Object, Lisp_Object,
2479 Lisp_Object, Lisp_Object, Lisp_Object, 2478 Lisp_Object, Lisp_Object, Lisp_Object,
2480 Lisp_Object); 2479 Lisp_Object);
2481int hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, unsigned *); 2480EMACS_INT hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *);
2482int hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object, 2481EMACS_INT hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object,
2483 unsigned); 2482 EMACS_UINT);
2484void init_weak_hash_tables (void); 2483void init_weak_hash_tables (void);
2485extern void init_fns (void); 2484extern void init_fns (void);
2486EXFUN (Fmake_hash_table, MANY); 2485EXFUN (Fmake_hash_table, MANY);
diff --git a/src/minibuf.c b/src/minibuf.c
index 4658b05e91d..39831e73b98 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -1209,7 +1209,7 @@ is used to further constrain the set of candidates. */)
1209 && (!SYMBOLP (XCAR (collection)) 1209 && (!SYMBOLP (XCAR (collection))
1210 || NILP (XCAR (collection))))) 1210 || NILP (XCAR (collection)))))
1211 ? list_table : function_table)); 1211 ? list_table : function_table));
1212 int idx = 0, obsize = 0; 1212 EMACS_INT idx = 0, obsize = 0;
1213 int matchcount = 0; 1213 int matchcount = 0;
1214 int bindcount = -1; 1214 int bindcount = -1;
1215 Lisp_Object bucket, zero, end, tem; 1215 Lisp_Object bucket, zero, end, tem;
@@ -1474,7 +1474,7 @@ with a space are ignored unless STRING itself starts with a space. */)
1474 : NILP (collection) || (CONSP (collection) 1474 : NILP (collection) || (CONSP (collection)
1475 && (!SYMBOLP (XCAR (collection)) 1475 && (!SYMBOLP (XCAR (collection))
1476 || NILP (XCAR (collection)))); 1476 || NILP (XCAR (collection))));
1477 int idx = 0, obsize = 0; 1477 EMACS_INT idx = 0, obsize = 0;
1478 int bindcount = -1; 1478 int bindcount = -1;
1479 Lisp_Object bucket, tem, zero; 1479 Lisp_Object bucket, tem, zero;
1480 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 1480 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
@@ -1770,7 +1770,7 @@ the values STRING, PREDICATE and `lambda'. */)
1770 (Lisp_Object string, Lisp_Object collection, Lisp_Object predicate) 1770 (Lisp_Object string, Lisp_Object collection, Lisp_Object predicate)
1771{ 1771{
1772 Lisp_Object regexps, tail, tem = Qnil; 1772 Lisp_Object regexps, tail, tem = Qnil;
1773 int i = 0; 1773 EMACS_INT i = 0;
1774 1774
1775 CHECK_STRING (string); 1775 CHECK_STRING (string);
1776 1776
diff --git a/src/print.c b/src/print.c
index 20c3e8ae526..803e3a17214 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1082,7 +1082,7 @@ print (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag)
1082 Maybe a better way to do that is to copy elements to 1082 Maybe a better way to do that is to copy elements to
1083 a new hash table. */ 1083 a new hash table. */
1084 struct Lisp_Hash_Table *h = XHASH_TABLE (Vprint_number_table); 1084 struct Lisp_Hash_Table *h = XHASH_TABLE (Vprint_number_table);
1085 int i; 1085 EMACS_INT i;
1086 1086
1087 for (i = 0; i < HASH_TABLE_SIZE (h); ++i) 1087 for (i = 0; i < HASH_TABLE_SIZE (h); ++i)
1088 if (!NILP (HASH_HASH (h, i)) 1088 if (!NILP (HASH_HASH (h, i))