aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2019-07-20 19:40:03 -0700
committerPaul Eggert2019-07-20 20:13:46 -0700
commit515afc9c15870cd7bd6b96e2d8b89938116923ac (patch)
treee57bf126a8e6076edb1c4fa87e4908c94fd8d779 /src
parentb6f194a0fb6dbd1b19aa01f95a955f5b8b23b40e (diff)
downloademacs-515afc9c15870cd7bd6b96e2d8b89938116923ac.tar.gz
emacs-515afc9c15870cd7bd6b96e2d8b89938116923ac.zip
Fix crash if user test munges hash table
* src/fns.c (restore_mutability) (hash_table_user_defined_call): New functions. (cmpfn_user_defined, hashfn_user_defined): Use them. (make_hash_table, copy_hash_table): Mark new hash table as mutable. (check_mutable_hash_table): New function. (Fclrhash, Fputhash, Fremhash): Use it instead of CHECK_IMPURE. * src/lisp.h (struct hash_table_test): User-defined functions now take pointers to struct Lisp_Hash_Table, not to struct hash_table_test. All uses changed. (struct Lisp_Hash_Table): New member ‘mutable’. * src/pdumper.c (dump_hash_table): Copy it. * test/src/fns-tests.el (test-hash-function-that-mutates-hash-table): New test, which tests for the bug.
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c1
-rw-r--r--src/bytecode.c5
-rw-r--r--src/composite.c2
-rw-r--r--src/fns.c74
-rw-r--r--src/lisp.h15
-rw-r--r--src/pdumper.c1
-rw-r--r--src/profiler.c8
7 files changed, 75 insertions, 31 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 09b3a4ea7e4..1718ce0fafc 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -5352,6 +5352,7 @@ purecopy_hash_table (struct Lisp_Hash_Table *table)
5352 pure->count = table->count; 5352 pure->count = table->count;
5353 pure->next_free = table->next_free; 5353 pure->next_free = table->next_free;
5354 pure->purecopy = table->purecopy; 5354 pure->purecopy = table->purecopy;
5355 eassert (!pure->mutable);
5355 pure->rehash_threshold = table->rehash_threshold; 5356 pure->rehash_threshold = table->rehash_threshold;
5356 pure->rehash_size = table->rehash_size; 5357 pure->rehash_size = table->rehash_size;
5357 pure->key_and_value = purecopy (table->key_and_value); 5358 pure->key_and_value = purecopy (table->key_and_value);
diff --git a/src/bytecode.c b/src/bytecode.c
index e82de026a82..d668a9a6a15 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -1410,14 +1410,13 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1410 { /* Do a linear search if there are not many cases 1410 { /* Do a linear search if there are not many cases
1411 FIXME: 5 is arbitrarily chosen. */ 1411 FIXME: 5 is arbitrarily chosen. */
1412 Lisp_Object hash_code 1412 Lisp_Object hash_code
1413 = h->test.cmpfn ? h->test.hashfn (v1, &h->test) : Qnil; 1413 = h->test.cmpfn ? h->test.hashfn (v1, h) : Qnil;
1414 1414
1415 for (i = h->count; 0 <= --i; ) 1415 for (i = h->count; 0 <= --i; )
1416 if (EQ (v1, HASH_KEY (h, i)) 1416 if (EQ (v1, HASH_KEY (h, i))
1417 || (h->test.cmpfn 1417 || (h->test.cmpfn
1418 && EQ (hash_code, HASH_HASH (h, i)) 1418 && EQ (hash_code, HASH_HASH (h, i))
1419 && !NILP (h->test.cmpfn (v1, HASH_KEY (h, i), 1419 && !NILP (h->test.cmpfn (v1, HASH_KEY (h, i), h))))
1420 &h->test))))
1421 break; 1420 break;
1422 } 1421 }
1423 else 1422 else
diff --git a/src/composite.c b/src/composite.c
index c36663f8e97..a6606d5fc45 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -655,7 +655,7 @@ composition_gstring_put_cache (Lisp_Object gstring, ptrdiff_t len)
655 struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table); 655 struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table);
656 hash_rehash_if_needed (h); 656 hash_rehash_if_needed (h);
657 Lisp_Object header = LGSTRING_HEADER (gstring); 657 Lisp_Object header = LGSTRING_HEADER (gstring);
658 Lisp_Object hash = h->test.hashfn (header, &h->test); 658 Lisp_Object hash = h->test.hashfn (header, h);
659 if (len < 0) 659 if (len < 0)
660 { 660 {
661 ptrdiff_t glyph_len = LGSTRING_GLYPH_LEN (gstring); 661 ptrdiff_t glyph_len = LGSTRING_GLYPH_LEN (gstring);
diff --git a/src/fns.c b/src/fns.c
index d9503c491eb..5f1ed07a120 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -3931,11 +3931,37 @@ HASH_INDEX (struct Lisp_Hash_Table *h, ptrdiff_t idx)
3931 return XFIXNUM (AREF (h->index, idx)); 3931 return XFIXNUM (AREF (h->index, idx));
3932} 3932}
3933 3933
3934/* Restore a hash table's mutability after the critical section exits. */
3935
3936static void
3937restore_mutability (void *ptr)
3938{
3939 struct Lisp_Hash_Table *h = ptr;
3940 h->mutable = true;
3941}
3942
3943/* Return the result of calling a user-defined hash or comparison
3944 function ARGS[0] with arguments ARGS[1] through ARGS[NARGS - 1].
3945 Signal an error if the function attempts to modify H, which
3946 otherwise might lead to undefined behavior. */
3947
3948static Lisp_Object
3949hash_table_user_defined_call (ptrdiff_t nargs, Lisp_Object *args,
3950 struct Lisp_Hash_Table *h)
3951{
3952 if (!h->mutable)
3953 return Ffuncall (nargs, args);
3954 ptrdiff_t count = inhibit_garbage_collection ();
3955 record_unwind_protect_ptr (restore_mutability, h);
3956 h->mutable = false;
3957 return unbind_to (count, Ffuncall (nargs, args));
3958}
3959
3934/* Ignore HT and compare KEY1 and KEY2 using 'eql'. 3960/* Ignore HT and compare KEY1 and KEY2 using 'eql'.
3935 Value is true if KEY1 and KEY2 are the same. */ 3961 Value is true if KEY1 and KEY2 are the same. */
3936 3962
3937static Lisp_Object 3963static Lisp_Object
3938cmpfn_eql (Lisp_Object key1, Lisp_Object key2, struct hash_table_test *ht) 3964cmpfn_eql (Lisp_Object key1, Lisp_Object key2, struct Lisp_Hash_Table *h)
3939{ 3965{
3940 return Feql (key1, key2); 3966 return Feql (key1, key2);
3941} 3967}
@@ -3944,7 +3970,7 @@ cmpfn_eql (Lisp_Object key1, Lisp_Object key2, struct hash_table_test *ht)
3944 Value is true if KEY1 and KEY2 are the same. */ 3970 Value is true if KEY1 and KEY2 are the same. */
3945 3971
3946static Lisp_Object 3972static Lisp_Object
3947cmpfn_equal (Lisp_Object key1, Lisp_Object key2, struct hash_table_test *ht) 3973cmpfn_equal (Lisp_Object key1, Lisp_Object key2, struct Lisp_Hash_Table *h)
3948{ 3974{
3949 return Fequal (key1, key2); 3975 return Fequal (key1, key2);
3950} 3976}
@@ -3955,16 +3981,17 @@ cmpfn_equal (Lisp_Object key1, Lisp_Object key2, struct hash_table_test *ht)
3955 3981
3956static Lisp_Object 3982static Lisp_Object
3957cmpfn_user_defined (Lisp_Object key1, Lisp_Object key2, 3983cmpfn_user_defined (Lisp_Object key1, Lisp_Object key2,
3958 struct hash_table_test *ht) 3984 struct Lisp_Hash_Table *h)
3959{ 3985{
3960 return call2 (ht->user_cmp_function, key1, key2); 3986 Lisp_Object args[] = { h->test.user_cmp_function, key1, key2 };
3987 return hash_table_user_defined_call (ARRAYELTS (args), args, h);
3961} 3988}
3962 3989
3963/* Ignore HT and return a hash code for KEY which uses 'eq' to compare 3990/* Ignore HT and return a hash code for KEY which uses 'eq' to compare
3964 keys. */ 3991 keys. */
3965 3992
3966static Lisp_Object 3993static Lisp_Object
3967hashfn_eq (Lisp_Object key, struct hash_table_test *ht) 3994hashfn_eq (Lisp_Object key, struct Lisp_Hash_Table *h)
3968{ 3995{
3969 return make_fixnum (XHASH (key) ^ XTYPE (key)); 3996 return make_fixnum (XHASH (key) ^ XTYPE (key));
3970} 3997}
@@ -3973,7 +4000,7 @@ hashfn_eq (Lisp_Object key, struct hash_table_test *ht)
3973 The hash code is at most INTMASK. */ 4000 The hash code is at most INTMASK. */
3974 4001
3975Lisp_Object 4002Lisp_Object
3976hashfn_equal (Lisp_Object key, struct hash_table_test *ht) 4003hashfn_equal (Lisp_Object key, struct Lisp_Hash_Table *h)
3977{ 4004{
3978 return make_fixnum (sxhash (key, 0)); 4005 return make_fixnum (sxhash (key, 0));
3979} 4006}
@@ -3982,19 +4009,19 @@ hashfn_equal (Lisp_Object key, struct hash_table_test *ht)
3982 The hash code is at most INTMASK. */ 4009 The hash code is at most INTMASK. */
3983 4010
3984Lisp_Object 4011Lisp_Object
3985hashfn_eql (Lisp_Object key, struct hash_table_test *ht) 4012hashfn_eql (Lisp_Object key, struct Lisp_Hash_Table *h)
3986{ 4013{
3987 return (FLOATP (key) || BIGNUMP (key) ? hashfn_equal : hashfn_eq) (key, ht); 4014 return (FLOATP (key) || BIGNUMP (key) ? hashfn_equal : hashfn_eq) (key, h);
3988} 4015}
3989 4016
3990/* Given HT, return a hash code for KEY which uses a user-defined 4017/* Given HT, return a hash code for KEY which uses a user-defined
3991 function to compare keys. */ 4018 function to compare keys. */
3992 4019
3993static Lisp_Object 4020static Lisp_Object
3994hashfn_user_defined (Lisp_Object key, struct hash_table_test *ht) 4021hashfn_user_defined (Lisp_Object key, struct Lisp_Hash_Table *h)
3995{ 4022{
3996 Lisp_Object hash = call1 (ht->user_hash_function, key); 4023 Lisp_Object args[] = { h->test.user_hash_function, key };
3997 return hashfn_eq (hash, ht); 4024 return hash_table_user_defined_call (ARRAYELTS (args), args, h);
3998} 4025}
3999 4026
4000struct hash_table_test const 4027struct hash_table_test const
@@ -4088,6 +4115,7 @@ make_hash_table (struct hash_table_test test, EMACS_INT size,
4088 h->index = make_vector (index_size, make_fixnum (-1)); 4115 h->index = make_vector (index_size, make_fixnum (-1));
4089 h->next_weak = NULL; 4116 h->next_weak = NULL;
4090 h->purecopy = purecopy; 4117 h->purecopy = purecopy;
4118 h->mutable = true;
4091 4119
4092 /* Set up the free list. */ 4120 /* Set up the free list. */
4093 for (i = 0; i < size - 1; ++i) 4121 for (i = 0; i < size - 1; ++i)
@@ -4113,6 +4141,7 @@ copy_hash_table (struct Lisp_Hash_Table *h1)
4113 4141
4114 h2 = allocate_hash_table (); 4142 h2 = allocate_hash_table ();
4115 *h2 = *h1; 4143 *h2 = *h1;
4144 h2->mutable = true;
4116 h2->key_and_value = Fcopy_sequence (h1->key_and_value); 4145 h2->key_and_value = Fcopy_sequence (h1->key_and_value);
4117 h2->hash = Fcopy_sequence (h1->hash); 4146 h2->hash = Fcopy_sequence (h1->hash);
4118 h2->next = Fcopy_sequence (h1->next); 4147 h2->next = Fcopy_sequence (h1->next);
@@ -4217,7 +4246,7 @@ hash_table_rehash (struct Lisp_Hash_Table *h)
4217 if (!NILP (HASH_HASH (h, i))) 4246 if (!NILP (HASH_HASH (h, i)))
4218 { 4247 {
4219 Lisp_Object key = HASH_KEY (h, i); 4248 Lisp_Object key = HASH_KEY (h, i);
4220 Lisp_Object hash_code = h->test.hashfn (key, &h->test); 4249 Lisp_Object hash_code = h->test.hashfn (key, h);
4221 set_hash_hash_slot (h, i, hash_code); 4250 set_hash_hash_slot (h, i, hash_code);
4222 } 4251 }
4223 4252
@@ -4255,7 +4284,7 @@ hash_lookup (struct Lisp_Hash_Table *h, Lisp_Object key, Lisp_Object *hash)
4255 4284
4256 hash_rehash_if_needed (h); 4285 hash_rehash_if_needed (h);
4257 4286
4258 Lisp_Object hash_code = h->test.hashfn (key, &h->test); 4287 Lisp_Object hash_code = h->test.hashfn (key, h);
4259 if (hash) 4288 if (hash)
4260 *hash = hash_code; 4289 *hash = hash_code;
4261 4290
@@ -4265,12 +4294,19 @@ hash_lookup (struct Lisp_Hash_Table *h, Lisp_Object key, Lisp_Object *hash)
4265 if (EQ (key, HASH_KEY (h, i)) 4294 if (EQ (key, HASH_KEY (h, i))
4266 || (h->test.cmpfn 4295 || (h->test.cmpfn
4267 && EQ (hash_code, HASH_HASH (h, i)) 4296 && EQ (hash_code, HASH_HASH (h, i))
4268 && !NILP (h->test.cmpfn (key, HASH_KEY (h, i), &h->test)))) 4297 && !NILP (h->test.cmpfn (key, HASH_KEY (h, i), h))))
4269 break; 4298 break;
4270 4299
4271 return i; 4300 return i;
4272} 4301}
4273 4302
4303static void
4304check_mutable_hash_table (Lisp_Object obj, struct Lisp_Hash_Table *h)
4305{
4306 if (!h->mutable)
4307 signal_error ("hash table test modifies table", obj);
4308 eassert (!PURE_P (h));
4309}
4274 4310
4275/* Put an entry into hash table H that associates KEY with VALUE. 4311/* Put an entry into hash table H that associates KEY with VALUE.
4276 HASH is a previously computed hash code of KEY. 4312 HASH is a previously computed hash code of KEY.
@@ -4310,7 +4346,7 @@ hash_put (struct Lisp_Hash_Table *h, Lisp_Object key, Lisp_Object value,
4310void 4346void
4311hash_remove_from_table (struct Lisp_Hash_Table *h, Lisp_Object key) 4347hash_remove_from_table (struct Lisp_Hash_Table *h, Lisp_Object key)
4312{ 4348{
4313 Lisp_Object hash_code = h->test.hashfn (key, &h->test); 4349 Lisp_Object hash_code = h->test.hashfn (key, h);
4314 ptrdiff_t start_of_bucket = XUFIXNUM (hash_code) % ASIZE (h->index); 4350 ptrdiff_t start_of_bucket = XUFIXNUM (hash_code) % ASIZE (h->index);
4315 ptrdiff_t prev = -1; 4351 ptrdiff_t prev = -1;
4316 4352
@@ -4323,7 +4359,7 @@ hash_remove_from_table (struct Lisp_Hash_Table *h, Lisp_Object key)
4323 if (EQ (key, HASH_KEY (h, i)) 4359 if (EQ (key, HASH_KEY (h, i))
4324 || (h->test.cmpfn 4360 || (h->test.cmpfn
4325 && EQ (hash_code, HASH_HASH (h, i)) 4361 && EQ (hash_code, HASH_HASH (h, i))
4326 && !NILP (h->test.cmpfn (key, HASH_KEY (h, i), &h->test)))) 4362 && !NILP (h->test.cmpfn (key, HASH_KEY (h, i), h))))
4327 { 4363 {
4328 /* Take entry out of collision chain. */ 4364 /* Take entry out of collision chain. */
4329 if (prev < 0) 4365 if (prev < 0)
@@ -4912,7 +4948,7 @@ DEFUN ("clrhash", Fclrhash, Sclrhash, 1, 1, 0,
4912 (Lisp_Object table) 4948 (Lisp_Object table)
4913{ 4949{
4914 struct Lisp_Hash_Table *h = check_hash_table (table); 4950 struct Lisp_Hash_Table *h = check_hash_table (table);
4915 CHECK_IMPURE (table, h); 4951 check_mutable_hash_table (table, h);
4916 hash_clear (h); 4952 hash_clear (h);
4917 /* Be compatible with XEmacs. */ 4953 /* Be compatible with XEmacs. */
4918 return table; 4954 return table;
@@ -4937,7 +4973,7 @@ VALUE. In any case, return VALUE. */)
4937 (Lisp_Object key, Lisp_Object value, Lisp_Object table) 4973 (Lisp_Object key, Lisp_Object value, Lisp_Object table)
4938{ 4974{
4939 struct Lisp_Hash_Table *h = check_hash_table (table); 4975 struct Lisp_Hash_Table *h = check_hash_table (table);
4940 CHECK_IMPURE (table, h); 4976 check_mutable_hash_table (table, h);
4941 4977
4942 Lisp_Object hash; 4978 Lisp_Object hash;
4943 ptrdiff_t i = hash_lookup (h, key, &hash); 4979 ptrdiff_t i = hash_lookup (h, key, &hash);
@@ -4955,7 +4991,7 @@ DEFUN ("remhash", Fremhash, Sremhash, 2, 2, 0,
4955 (Lisp_Object key, Lisp_Object table) 4991 (Lisp_Object key, Lisp_Object table)
4956{ 4992{
4957 struct Lisp_Hash_Table *h = check_hash_table (table); 4993 struct Lisp_Hash_Table *h = check_hash_table (table);
4958 CHECK_IMPURE (table, h); 4994 check_mutable_hash_table (table, h);
4959 hash_remove_from_table (h, key); 4995 hash_remove_from_table (h, key);
4960 return Qnil; 4996 return Qnil;
4961} 4997}
diff --git a/src/lisp.h b/src/lisp.h
index e5edb8fd125..6d101fed908 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2225,6 +2225,8 @@ INLINE int
2225 2225
2226/* The structure of a Lisp hash table. */ 2226/* The structure of a Lisp hash table. */
2227 2227
2228struct Lisp_Hash_Table;
2229
2228struct hash_table_test 2230struct hash_table_test
2229{ 2231{
2230 /* Name of the function used to compare keys. */ 2232 /* Name of the function used to compare keys. */
@@ -2237,10 +2239,10 @@ struct hash_table_test
2237 Lisp_Object user_cmp_function; 2239 Lisp_Object user_cmp_function;
2238 2240
2239 /* C function to compare two keys. */ 2241 /* C function to compare two keys. */
2240 Lisp_Object (*cmpfn) (Lisp_Object, Lisp_Object, struct hash_table_test *t); 2242 Lisp_Object (*cmpfn) (Lisp_Object, Lisp_Object, struct Lisp_Hash_Table *);
2241 2243
2242 /* C function to compute hash code. */ 2244 /* C function to compute hash code. */
2243 Lisp_Object (*hashfn) (Lisp_Object, struct hash_table_test *t); 2245 Lisp_Object (*hashfn) (Lisp_Object, struct Lisp_Hash_Table *);
2244}; 2246};
2245 2247
2246struct Lisp_Hash_Table 2248struct Lisp_Hash_Table
@@ -2289,6 +2291,11 @@ struct Lisp_Hash_Table
2289 changed afterwards. */ 2291 changed afterwards. */
2290 bool purecopy; 2292 bool purecopy;
2291 2293
2294 /* True if the table is mutable. Ordinarily tables are mutable, but
2295 pure tables are not, and while a table is being mutated it is
2296 immutable for recursive attempts to mutate it. */
2297 bool mutable;
2298
2292 /* Resize hash table when number of entries / table size is >= this 2299 /* Resize hash table when number of entries / table size is >= this
2293 ratio. */ 2300 ratio. */
2294 float rehash_threshold; 2301 float rehash_threshold;
@@ -3591,8 +3598,8 @@ extern void hexbuf_digest (char *, void const *, int);
3591extern char *extract_data_from_object (Lisp_Object, ptrdiff_t *, ptrdiff_t *); 3598extern char *extract_data_from_object (Lisp_Object, ptrdiff_t *, ptrdiff_t *);
3592EMACS_UINT hash_string (char const *, ptrdiff_t); 3599EMACS_UINT hash_string (char const *, ptrdiff_t);
3593EMACS_UINT sxhash (Lisp_Object, int); 3600EMACS_UINT sxhash (Lisp_Object, int);
3594Lisp_Object hashfn_eql (Lisp_Object, struct hash_table_test *); 3601Lisp_Object hashfn_eql (Lisp_Object, struct Lisp_Hash_Table *);
3595Lisp_Object hashfn_equal (Lisp_Object, struct hash_table_test *); 3602Lisp_Object hashfn_equal (Lisp_Object, struct Lisp_Hash_Table *);
3596Lisp_Object make_hash_table (struct hash_table_test, EMACS_INT, float, float, 3603Lisp_Object make_hash_table (struct hash_table_test, EMACS_INT, float, float,
3597 Lisp_Object, bool); 3604 Lisp_Object, bool);
3598ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object *); 3605ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object *);
diff --git a/src/pdumper.c b/src/pdumper.c
index 206a1968909..2abac80a372 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -2742,6 +2742,7 @@ dump_hash_table (struct dump_context *ctx,
2742 DUMP_FIELD_COPY (out, hash, count); 2742 DUMP_FIELD_COPY (out, hash, count);
2743 DUMP_FIELD_COPY (out, hash, next_free); 2743 DUMP_FIELD_COPY (out, hash, next_free);
2744 DUMP_FIELD_COPY (out, hash, purecopy); 2744 DUMP_FIELD_COPY (out, hash, purecopy);
2745 DUMP_FIELD_COPY (out, hash, mutable);
2745 DUMP_FIELD_COPY (out, hash, rehash_threshold); 2746 DUMP_FIELD_COPY (out, hash, rehash_threshold);
2746 DUMP_FIELD_COPY (out, hash, rehash_size); 2747 DUMP_FIELD_COPY (out, hash, rehash_size);
2747 dump_field_lv (ctx, out, hash, &hash->key_and_value, WEIGHT_STRONG); 2748 dump_field_lv (ctx, out, hash, &hash->key_and_value, WEIGHT_STRONG);
diff --git a/src/profiler.c b/src/profiler.c
index e9b6a37d06b..ed0e9ddd881 100644
--- a/src/profiler.c
+++ b/src/profiler.c
@@ -37,8 +37,8 @@ saturated_add (EMACS_INT a, EMACS_INT b)
37typedef struct Lisp_Hash_Table log_t; 37typedef struct Lisp_Hash_Table log_t;
38 38
39static Lisp_Object cmpfn_profiler (Lisp_Object, Lisp_Object, 39static Lisp_Object cmpfn_profiler (Lisp_Object, Lisp_Object,
40 struct hash_table_test *); 40 struct Lisp_Hash_Table *);
41static Lisp_Object hashfn_profiler (Lisp_Object, struct hash_table_test *); 41static Lisp_Object hashfn_profiler (Lisp_Object, struct Lisp_Hash_Table *);
42 42
43static const struct hash_table_test hashtest_profiler = 43static const struct hash_table_test hashtest_profiler =
44 { 44 {
@@ -528,7 +528,7 @@ the same lambda expression, or are really unrelated function. */)
528} 528}
529 529
530static Lisp_Object 530static Lisp_Object
531cmpfn_profiler (Lisp_Object bt1, Lisp_Object bt2, struct hash_table_test *t) 531cmpfn_profiler (Lisp_Object bt1, Lisp_Object bt2, struct Lisp_Hash_Table *h)
532{ 532{
533 if (VECTORP (bt1) && VECTORP (bt2)) 533 if (VECTORP (bt1) && VECTORP (bt2))
534 { 534 {
@@ -545,7 +545,7 @@ cmpfn_profiler (Lisp_Object bt1, Lisp_Object bt2, struct hash_table_test *t)
545} 545}
546 546
547static Lisp_Object 547static Lisp_Object
548hashfn_profiler (Lisp_Object bt, struct hash_table_test *ht) 548hashfn_profiler (Lisp_Object bt, struct Lisp_Hash_Table *h)
549{ 549{
550 EMACS_UINT hash; 550 EMACS_UINT hash;
551 if (VECTORP (bt)) 551 if (VECTORP (bt))