diff options
| author | Mattias EngdegÄrd | 2023-11-02 17:05:26 +0100 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2024-01-13 20:50:38 +0100 |
| commit | 7d93a0147a14e14d6964bf93ba11cf494b9d49fd (patch) | |
| tree | 2cce6ad4b4476616e0be3dc1fcf5f68d2ae7692d /src | |
| parent | 0a998938ca1b7e5e6f09d14b4a62ec7089be2af6 (diff) | |
| download | emacs-7d93a0147a14e14d6964bf93ba11cf494b9d49fd.tar.gz emacs-7d93a0147a14e14d6964bf93ba11cf494b9d49fd.zip | |
Share hash table test structs
This saves several words in the hash table object at the cost of an
indirection at runtime. This seems to be a gain in overall
performance.
FIXME: We cache hash test objects in a rather clumsy way. A better
solution is sought.
* src/lisp.h (struct Lisp_Hash_Table): Use a pointer to the test
struct. All references adapted.
* src/alloc.c (garbage_collect):
* src/fns.c (struct hash_table_user_test, hash_table_user_tests)
(mark_fns, get_hash_table_user_test): New state for caching test
structs, and functions managing it.
Diffstat (limited to 'src')
| -rw-r--r-- | src/alloc.c | 8 | ||||
| -rw-r--r-- | src/bytecode.c | 2 | ||||
| -rw-r--r-- | src/category.c | 2 | ||||
| -rw-r--r-- | src/emacs-module.c | 2 | ||||
| -rw-r--r-- | src/fns.c | 92 | ||||
| -rw-r--r-- | src/frame.c | 2 | ||||
| -rw-r--r-- | src/image.c | 2 | ||||
| -rw-r--r-- | src/lisp.h | 8 | ||||
| -rw-r--r-- | src/lread.c | 8 | ||||
| -rw-r--r-- | src/pdumper.c | 3 | ||||
| -rw-r--r-- | src/pgtkterm.c | 2 | ||||
| -rw-r--r-- | src/print.c | 4 | ||||
| -rw-r--r-- | src/profiler.c | 2 | ||||
| -rw-r--r-- | src/xfaces.c | 2 | ||||
| -rw-r--r-- | src/xterm.c | 2 |
15 files changed, 90 insertions, 51 deletions
diff --git a/src/alloc.c b/src/alloc.c index 7432163db25..16aaa32e15f 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -5942,10 +5942,6 @@ purecopy_hash_table (struct Lisp_Hash_Table *table) | |||
| 5942 | *pure = *table; | 5942 | *pure = *table; |
| 5943 | pure->mutable = false; | 5943 | pure->mutable = false; |
| 5944 | 5944 | ||
| 5945 | pure->test.name = purecopy (table->test.name); | ||
| 5946 | pure->test.user_hash_function = purecopy (table->test.user_hash_function); | ||
| 5947 | pure->test.user_cmp_function = purecopy (table->test.user_cmp_function); | ||
| 5948 | |||
| 5949 | if (table->table_size > 0) | 5945 | if (table->table_size > 0) |
| 5950 | { | 5946 | { |
| 5951 | ptrdiff_t hash_bytes = table->table_size * sizeof *table->hash; | 5947 | ptrdiff_t hash_bytes = table->table_size * sizeof *table->hash; |
| @@ -6630,6 +6626,7 @@ garbage_collect (void) | |||
| 6630 | #ifdef HAVE_NS | 6626 | #ifdef HAVE_NS |
| 6631 | mark_nsterm (); | 6627 | mark_nsterm (); |
| 6632 | #endif | 6628 | #endif |
| 6629 | mark_fns (); | ||
| 6633 | 6630 | ||
| 6634 | /* Everything is now marked, except for the data in font caches, | 6631 | /* Everything is now marked, except for the data in font caches, |
| 6635 | undo lists, and finalizers. The first two are compacted by | 6632 | undo lists, and finalizers. The first two are compacted by |
| @@ -7295,9 +7292,6 @@ process_mark_stack (ptrdiff_t base_sp) | |||
| 7295 | { | 7292 | { |
| 7296 | struct Lisp_Hash_Table *h = (struct Lisp_Hash_Table *)ptr; | 7293 | struct Lisp_Hash_Table *h = (struct Lisp_Hash_Table *)ptr; |
| 7297 | set_vector_marked (ptr); | 7294 | set_vector_marked (ptr); |
| 7298 | mark_stack_push_value (h->test.name); | ||
| 7299 | mark_stack_push_value (h->test.user_hash_function); | ||
| 7300 | mark_stack_push_value (h->test.user_cmp_function); | ||
| 7301 | if (h->weakness == Weak_None) | 7295 | if (h->weakness == Weak_None) |
| 7302 | mark_stack_push_values (h->key_and_value, | 7296 | mark_stack_push_values (h->key_and_value, |
| 7303 | 2 * h->table_size); | 7297 | 2 * h->table_size); |
diff --git a/src/bytecode.c b/src/bytecode.c index a0f02d518b7..ed6e2b34e77 100644 --- a/src/bytecode.c +++ b/src/bytecode.c | |||
| @@ -1743,7 +1743,7 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template, | |||
| 1743 | 1743 | ||
| 1744 | /* h->count is a faster approximation for HASH_TABLE_SIZE (h) | 1744 | /* h->count is a faster approximation for HASH_TABLE_SIZE (h) |
| 1745 | here. */ | 1745 | here. */ |
| 1746 | if (h->count <= 5 && !h->test.cmpfn) | 1746 | if (h->count <= 5 && !h->test->cmpfn) |
| 1747 | { /* Do a linear search if there are not many cases | 1747 | { /* Do a linear search if there are not many cases |
| 1748 | FIXME: 5 is arbitrarily chosen. */ | 1748 | FIXME: 5 is arbitrarily chosen. */ |
| 1749 | for (i = h->count; 0 <= --i; ) | 1749 | for (i = h->count; 0 <= --i; ) |
diff --git a/src/category.c b/src/category.c index 3a406a567a1..498b6a2a1c9 100644 --- a/src/category.c +++ b/src/category.c | |||
| @@ -51,7 +51,7 @@ hash_get_category_set (Lisp_Object table, Lisp_Object category_set) | |||
| 51 | if (NILP (XCHAR_TABLE (table)->extras[1])) | 51 | if (NILP (XCHAR_TABLE (table)->extras[1])) |
| 52 | set_char_table_extras | 52 | set_char_table_extras |
| 53 | (table, 1, | 53 | (table, 1, |
| 54 | make_hash_table (hashtest_equal, DEFAULT_HASH_SIZE, Weak_None, false)); | 54 | make_hash_table (&hashtest_equal, DEFAULT_HASH_SIZE, Weak_None, false)); |
| 55 | struct Lisp_Hash_Table *h = XHASH_TABLE (XCHAR_TABLE (table)->extras[1]); | 55 | struct Lisp_Hash_Table *h = XHASH_TABLE (XCHAR_TABLE (table)->extras[1]); |
| 56 | hash_hash_t hash; | 56 | hash_hash_t hash; |
| 57 | ptrdiff_t i = hash_lookup_get_hash (h, category_set, &hash); | 57 | ptrdiff_t i = hash_lookup_get_hash (h, category_set, &hash); |
diff --git a/src/emacs-module.c b/src/emacs-module.c index e78391b3a71..00ae33dfa2c 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c | |||
| @@ -1698,7 +1698,7 @@ syms_of_module (void) | |||
| 1698 | { | 1698 | { |
| 1699 | staticpro (&Vmodule_refs_hash); | 1699 | staticpro (&Vmodule_refs_hash); |
| 1700 | Vmodule_refs_hash | 1700 | Vmodule_refs_hash |
| 1701 | = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, Weak_None, false); | 1701 | = make_hash_table (&hashtest_eq, DEFAULT_HASH_SIZE, Weak_None, false); |
| 1702 | 1702 | ||
| 1703 | DEFSYM (Qmodule_load_failed, "module-load-failed"); | 1703 | DEFSYM (Qmodule_load_failed, "module-load-failed"); |
| 1704 | Fput (Qmodule_load_failed, Qerror_conditions, | 1704 | Fput (Qmodule_load_failed, Qerror_conditions, |
| @@ -4448,7 +4448,7 @@ static Lisp_Object | |||
| 4448 | cmpfn_user_defined (Lisp_Object key1, Lisp_Object key2, | 4448 | cmpfn_user_defined (Lisp_Object key1, Lisp_Object key2, |
| 4449 | struct Lisp_Hash_Table *h) | 4449 | struct Lisp_Hash_Table *h) |
| 4450 | { | 4450 | { |
| 4451 | Lisp_Object args[] = { h->test.user_cmp_function, key1, key2 }; | 4451 | Lisp_Object args[] = { h->test->user_cmp_function, key1, key2 }; |
| 4452 | return hash_table_user_defined_call (ARRAYELTS (args), args, h); | 4452 | return hash_table_user_defined_call (ARRAYELTS (args), args, h); |
| 4453 | } | 4453 | } |
| 4454 | 4454 | ||
| @@ -4487,7 +4487,7 @@ hashfn_eql (Lisp_Object key, struct Lisp_Hash_Table *h) | |||
| 4487 | static hash_hash_t | 4487 | static hash_hash_t |
| 4488 | hashfn_user_defined (Lisp_Object key, struct Lisp_Hash_Table *h) | 4488 | hashfn_user_defined (Lisp_Object key, struct Lisp_Hash_Table *h) |
| 4489 | { | 4489 | { |
| 4490 | Lisp_Object args[] = { h->test.user_hash_function, key }; | 4490 | Lisp_Object args[] = { h->test->user_hash_function, key }; |
| 4491 | Lisp_Object hash = hash_table_user_defined_call (ARRAYELTS (args), args, h); | 4491 | Lisp_Object hash = hash_table_user_defined_call (ARRAYELTS (args), args, h); |
| 4492 | return FIXNUMP (hash) ? XUFIXNUM(hash) : sxhash (hash); | 4492 | return FIXNUMP (hash) ? XUFIXNUM(hash) : sxhash (hash); |
| 4493 | } | 4493 | } |
| @@ -4557,10 +4557,10 @@ static const hash_idx_t empty_hash_index_vector[] = {-1}; | |||
| 4557 | changed after purecopy. */ | 4557 | changed after purecopy. */ |
| 4558 | 4558 | ||
| 4559 | Lisp_Object | 4559 | Lisp_Object |
| 4560 | make_hash_table (struct hash_table_test test, EMACS_INT size, | 4560 | make_hash_table (const struct hash_table_test *test, EMACS_INT size, |
| 4561 | hash_table_weakness_t weak, bool purecopy) | 4561 | hash_table_weakness_t weak, bool purecopy) |
| 4562 | { | 4562 | { |
| 4563 | eassert (SYMBOLP (test.name)); | 4563 | eassert (SYMBOLP (test->name)); |
| 4564 | eassert (0 <= size && size <= min (MOST_POSITIVE_FIXNUM, PTRDIFF_MAX)); | 4564 | eassert (0 <= size && size <= min (MOST_POSITIVE_FIXNUM, PTRDIFF_MAX)); |
| 4565 | 4565 | ||
| 4566 | struct Lisp_Hash_Table *h = allocate_hash_table (); | 4566 | struct Lisp_Hash_Table *h = allocate_hash_table (); |
| @@ -4763,7 +4763,7 @@ hash_table_thaw (Lisp_Object hash_table) | |||
| 4763 | 4763 | ||
| 4764 | /* Freezing discarded most non-essential information; recompute it. | 4764 | /* Freezing discarded most non-essential information; recompute it. |
| 4765 | The allocation is minimal with no room for growth. */ | 4765 | The allocation is minimal with no room for growth. */ |
| 4766 | h->test = *hash_table_test_from_std (h->frozen_test); | 4766 | h->test = hash_table_test_from_std (h->frozen_test); |
| 4767 | ptrdiff_t size = h->count; | 4767 | ptrdiff_t size = h->count; |
| 4768 | h->table_size = size; | 4768 | h->table_size = size; |
| 4769 | ptrdiff_t index_size = hash_index_size (size); | 4769 | ptrdiff_t index_size = hash_index_size (size); |
| @@ -4805,9 +4805,9 @@ hash_lookup_with_hash (struct Lisp_Hash_Table *h, | |||
| 4805 | for (ptrdiff_t i = HASH_INDEX (h, start_of_bucket); | 4805 | for (ptrdiff_t i = HASH_INDEX (h, start_of_bucket); |
| 4806 | 0 <= i; i = HASH_NEXT (h, i)) | 4806 | 0 <= i; i = HASH_NEXT (h, i)) |
| 4807 | if (EQ (key, HASH_KEY (h, i)) | 4807 | if (EQ (key, HASH_KEY (h, i)) |
| 4808 | || (h->test.cmpfn | 4808 | || (h->test->cmpfn |
| 4809 | && hash == HASH_HASH (h, i) | 4809 | && hash == HASH_HASH (h, i) |
| 4810 | && !NILP (h->test.cmpfn (key, HASH_KEY (h, i), h)))) | 4810 | && !NILP (h->test->cmpfn (key, HASH_KEY (h, i), h)))) |
| 4811 | return i; | 4811 | return i; |
| 4812 | 4812 | ||
| 4813 | return -1; | 4813 | return -1; |
| @@ -4884,9 +4884,9 @@ hash_remove_from_table (struct Lisp_Hash_Table *h, Lisp_Object key) | |||
| 4884 | i = HASH_NEXT (h, i)) | 4884 | i = HASH_NEXT (h, i)) |
| 4885 | { | 4885 | { |
| 4886 | if (EQ (key, HASH_KEY (h, i)) | 4886 | if (EQ (key, HASH_KEY (h, i)) |
| 4887 | || (h->test.cmpfn | 4887 | || (h->test->cmpfn |
| 4888 | && hashval == HASH_HASH (h, i) | 4888 | && hashval == HASH_HASH (h, i) |
| 4889 | && !NILP (h->test.cmpfn (key, HASH_KEY (h, i), h)))) | 4889 | && !NILP (h->test->cmpfn (key, HASH_KEY (h, i), h)))) |
| 4890 | { | 4890 | { |
| 4891 | /* Take entry out of collision chain. */ | 4891 | /* Take entry out of collision chain. */ |
| 4892 | if (prev < 0) | 4892 | if (prev < 0) |
| @@ -5339,6 +5339,58 @@ Hash codes are not guaranteed to be preserved across Emacs sessions. */) | |||
| 5339 | return make_ufixnum (hashfn_equal (obj, NULL)); | 5339 | return make_ufixnum (hashfn_equal (obj, NULL)); |
| 5340 | } | 5340 | } |
| 5341 | 5341 | ||
| 5342 | |||
| 5343 | /* This is a cache of hash_table_test structures so that they can be | ||
| 5344 | shared between hash tables using the same test. | ||
| 5345 | FIXME: This way of storing and looking up hash_table_test structs | ||
| 5346 | isn't wonderful. Find a better solution. */ | ||
| 5347 | struct hash_table_user_test | ||
| 5348 | { | ||
| 5349 | struct hash_table_test test; | ||
| 5350 | struct hash_table_user_test *next; | ||
| 5351 | }; | ||
| 5352 | |||
| 5353 | static struct hash_table_user_test *hash_table_user_tests = NULL; | ||
| 5354 | |||
| 5355 | void | ||
| 5356 | mark_fns (void) | ||
| 5357 | { | ||
| 5358 | for (struct hash_table_user_test *ut = hash_table_user_tests; | ||
| 5359 | ut; ut = ut->next) | ||
| 5360 | { | ||
| 5361 | mark_object (ut->test.name); | ||
| 5362 | mark_object (ut->test.user_cmp_function); | ||
| 5363 | mark_object (ut->test.user_hash_function); | ||
| 5364 | } | ||
| 5365 | } | ||
| 5366 | |||
| 5367 | static struct hash_table_test * | ||
| 5368 | get_hash_table_user_test (Lisp_Object test) | ||
| 5369 | { | ||
| 5370 | Lisp_Object prop = Fget (test, Qhash_table_test); | ||
| 5371 | if (!CONSP (prop) || !CONSP (XCDR (prop))) | ||
| 5372 | signal_error ("Invalid hash table test", test); | ||
| 5373 | |||
| 5374 | Lisp_Object equal_fn = XCAR (prop); | ||
| 5375 | Lisp_Object hash_fn = XCAR (XCDR (prop)); | ||
| 5376 | struct hash_table_user_test *ut = hash_table_user_tests; | ||
| 5377 | while (ut && !(EQ (equal_fn, ut->test.user_cmp_function) | ||
| 5378 | && EQ (hash_fn, ut->test.user_hash_function))) | ||
| 5379 | ut = ut->next; | ||
| 5380 | if (!ut) | ||
| 5381 | { | ||
| 5382 | ut = xmalloc (sizeof *ut); | ||
| 5383 | ut->test.name = test; | ||
| 5384 | ut->test.user_cmp_function = equal_fn; | ||
| 5385 | ut->test.user_hash_function = hash_fn; | ||
| 5386 | ut->test.hashfn = hashfn_user_defined; | ||
| 5387 | ut->test.cmpfn = cmpfn_user_defined; | ||
| 5388 | ut->next = hash_table_user_tests; | ||
| 5389 | hash_table_user_tests = ut; | ||
| 5390 | } | ||
| 5391 | return &ut->test; | ||
| 5392 | } | ||
| 5393 | |||
| 5342 | DEFUN ("make-hash-table", Fmake_hash_table, Smake_hash_table, 0, MANY, 0, | 5394 | DEFUN ("make-hash-table", Fmake_hash_table, Smake_hash_table, 0, MANY, 0, |
| 5343 | doc: /* Create and return a new hash table. | 5395 | doc: /* Create and return a new hash table. |
| 5344 | 5396 | ||
| @@ -5384,25 +5436,15 @@ usage: (make-hash-table &rest KEYWORD-ARGS) */) | |||
| 5384 | Lisp_Object test = i ? args[i] : Qeql; | 5436 | Lisp_Object test = i ? args[i] : Qeql; |
| 5385 | if (symbols_with_pos_enabled && SYMBOL_WITH_POS_P (test)) | 5437 | if (symbols_with_pos_enabled && SYMBOL_WITH_POS_P (test)) |
| 5386 | test = SYMBOL_WITH_POS_SYM (test); | 5438 | test = SYMBOL_WITH_POS_SYM (test); |
| 5387 | struct hash_table_test testdesc; | 5439 | const struct hash_table_test *testdesc; |
| 5388 | if (BASE_EQ (test, Qeq)) | 5440 | if (BASE_EQ (test, Qeq)) |
| 5389 | testdesc = hashtest_eq; | 5441 | testdesc = &hashtest_eq; |
| 5390 | else if (BASE_EQ (test, Qeql)) | 5442 | else if (BASE_EQ (test, Qeql)) |
| 5391 | testdesc = hashtest_eql; | 5443 | testdesc = &hashtest_eql; |
| 5392 | else if (BASE_EQ (test, Qequal)) | 5444 | else if (BASE_EQ (test, Qequal)) |
| 5393 | testdesc = hashtest_equal; | 5445 | testdesc = &hashtest_equal; |
| 5394 | else | 5446 | else |
| 5395 | { | 5447 | testdesc = get_hash_table_user_test (test); |
| 5396 | /* See if it is a user-defined test. */ | ||
| 5397 | Lisp_Object prop = Fget (test, Qhash_table_test); | ||
| 5398 | if (!CONSP (prop) || !CONSP (XCDR (prop))) | ||
| 5399 | signal_error ("Invalid hash table test", test); | ||
| 5400 | testdesc.name = test; | ||
| 5401 | testdesc.user_cmp_function = XCAR (prop); | ||
| 5402 | testdesc.user_hash_function = XCAR (XCDR (prop)); | ||
| 5403 | testdesc.hashfn = hashfn_user_defined; | ||
| 5404 | testdesc.cmpfn = cmpfn_user_defined; | ||
| 5405 | } | ||
| 5406 | 5448 | ||
| 5407 | /* See if there's a `:purecopy PURECOPY' argument. */ | 5449 | /* See if there's a `:purecopy PURECOPY' argument. */ |
| 5408 | i = get_key_arg (QCpurecopy, nargs, args, used); | 5450 | i = get_key_arg (QCpurecopy, nargs, args, used); |
| @@ -5504,7 +5546,7 @@ DEFUN ("hash-table-test", Fhash_table_test, Shash_table_test, 1, 1, 0, | |||
| 5504 | doc: /* Return the test TABLE uses. */) | 5546 | doc: /* Return the test TABLE uses. */) |
| 5505 | (Lisp_Object table) | 5547 | (Lisp_Object table) |
| 5506 | { | 5548 | { |
| 5507 | return check_hash_table (table)->test.name; | 5549 | return check_hash_table (table)->test->name; |
| 5508 | } | 5550 | } |
| 5509 | 5551 | ||
| 5510 | Lisp_Object | 5552 | Lisp_Object |
diff --git a/src/frame.c b/src/frame.c index 08057736272..abd6ef00901 100644 --- a/src/frame.c +++ b/src/frame.c | |||
| @@ -1040,7 +1040,7 @@ make_frame (bool mini_p) | |||
| 1040 | rw->pixel_height = rw->total_lines * FRAME_LINE_HEIGHT (f); | 1040 | rw->pixel_height = rw->total_lines * FRAME_LINE_HEIGHT (f); |
| 1041 | 1041 | ||
| 1042 | fset_face_hash_table | 1042 | fset_face_hash_table |
| 1043 | (f, make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, Weak_None, false)); | 1043 | (f, make_hash_table (&hashtest_eq, DEFAULT_HASH_SIZE, Weak_None, false)); |
| 1044 | 1044 | ||
| 1045 | if (mini_p) | 1045 | if (mini_p) |
| 1046 | { | 1046 | { |
diff --git a/src/image.c b/src/image.c index 74d4b6c0bfe..66838adbb2a 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -6069,7 +6069,7 @@ xpm_make_color_table_h (void (**put_func) (Lisp_Object, const char *, int, | |||
| 6069 | { | 6069 | { |
| 6070 | *put_func = xpm_put_color_table_h; | 6070 | *put_func = xpm_put_color_table_h; |
| 6071 | *get_func = xpm_get_color_table_h; | 6071 | *get_func = xpm_get_color_table_h; |
| 6072 | return make_hash_table (hashtest_equal, DEFAULT_HASH_SIZE, Weak_None, false); | 6072 | return make_hash_table (&hashtest_equal, DEFAULT_HASH_SIZE, Weak_None, false); |
| 6073 | } | 6073 | } |
| 6074 | 6074 | ||
| 6075 | static void | 6075 | static void |
diff --git a/src/lisp.h b/src/lisp.h index 33c1e345f7a..b11237381d9 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -2397,6 +2397,7 @@ typedef enum { | |||
| 2397 | 2397 | ||
| 2398 | struct hash_table_test | 2398 | struct hash_table_test |
| 2399 | { | 2399 | { |
| 2400 | /* FIXME: reorder for efficiency */ | ||
| 2400 | /* Function used to compare keys; always a bare symbol. */ | 2401 | /* Function used to compare keys; always a bare symbol. */ |
| 2401 | Lisp_Object name; | 2402 | Lisp_Object name; |
| 2402 | 2403 | ||
| @@ -2515,7 +2516,7 @@ struct Lisp_Hash_Table | |||
| 2515 | Lisp_Object *key_and_value; | 2516 | Lisp_Object *key_and_value; |
| 2516 | 2517 | ||
| 2517 | /* The comparison and hash functions. */ | 2518 | /* The comparison and hash functions. */ |
| 2518 | struct hash_table_test test; | 2519 | const struct hash_table_test *test; |
| 2519 | 2520 | ||
| 2520 | /* Next weak hash table if this is a weak hash table. The head of | 2521 | /* Next weak hash table if this is a weak hash table. The head of |
| 2521 | the list is in weak_hash_tables. Used only during garbage | 2522 | the list is in weak_hash_tables. Used only during garbage |
| @@ -2584,7 +2585,7 @@ HASH_TABLE_SIZE (const struct Lisp_Hash_Table *h) | |||
| 2584 | INLINE hash_hash_t | 2585 | INLINE hash_hash_t |
| 2585 | hash_from_key (struct Lisp_Hash_Table *h, Lisp_Object key) | 2586 | hash_from_key (struct Lisp_Hash_Table *h, Lisp_Object key) |
| 2586 | { | 2587 | { |
| 2587 | return h->test.hashfn (key, h); | 2588 | return h->test->hashfn (key, h); |
| 2588 | } | 2589 | } |
| 2589 | 2590 | ||
| 2590 | void hash_table_thaw (Lisp_Object hash_table); | 2591 | void hash_table_thaw (Lisp_Object hash_table); |
| @@ -4064,7 +4065,7 @@ extern void hexbuf_digest (char *, void const *, int); | |||
| 4064 | extern char *extract_data_from_object (Lisp_Object, ptrdiff_t *, ptrdiff_t *); | 4065 | extern char *extract_data_from_object (Lisp_Object, ptrdiff_t *, ptrdiff_t *); |
| 4065 | EMACS_UINT hash_string (char const *, ptrdiff_t); | 4066 | EMACS_UINT hash_string (char const *, ptrdiff_t); |
| 4066 | EMACS_UINT sxhash (Lisp_Object); | 4067 | EMACS_UINT sxhash (Lisp_Object); |
| 4067 | Lisp_Object make_hash_table (struct hash_table_test, EMACS_INT, | 4068 | Lisp_Object make_hash_table (const struct hash_table_test *, EMACS_INT, |
| 4068 | hash_table_weakness_t, bool); | 4069 | hash_table_weakness_t, bool); |
| 4069 | Lisp_Object hash_table_weakness_symbol (hash_table_weakness_t weak); | 4070 | Lisp_Object hash_table_weakness_symbol (hash_table_weakness_t weak); |
| 4070 | ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object); | 4071 | ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object); |
| @@ -4098,6 +4099,7 @@ extern Lisp_Object plist_put (Lisp_Object plist, Lisp_Object prop, | |||
| 4098 | Lisp_Object val); | 4099 | Lisp_Object val); |
| 4099 | extern Lisp_Object plist_member (Lisp_Object plist, Lisp_Object prop); | 4100 | extern Lisp_Object plist_member (Lisp_Object plist, Lisp_Object prop); |
| 4100 | extern void syms_of_fns (void); | 4101 | extern void syms_of_fns (void); |
| 4102 | extern void mark_fns (void); | ||
| 4101 | 4103 | ||
| 4102 | /* Defined in sort.c */ | 4104 | /* Defined in sort.c */ |
| 4103 | extern void tim_sort (Lisp_Object, Lisp_Object *, const ptrdiff_t); | 4105 | extern void tim_sort (Lisp_Object, Lisp_Object *, const ptrdiff_t); |
diff --git a/src/lread.c b/src/lread.c index b76fde3f266..2c6a444ec56 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -2544,11 +2544,11 @@ readevalloop (Lisp_Object readcharfun, | |||
| 2544 | if (! HASH_TABLE_P (read_objects_map) | 2544 | if (! HASH_TABLE_P (read_objects_map) |
| 2545 | || XHASH_TABLE (read_objects_map)->count) | 2545 | || XHASH_TABLE (read_objects_map)->count) |
| 2546 | read_objects_map | 2546 | read_objects_map |
| 2547 | = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, Weak_None, false); | 2547 | = make_hash_table (&hashtest_eq, DEFAULT_HASH_SIZE, Weak_None, false); |
| 2548 | if (! HASH_TABLE_P (read_objects_completed) | 2548 | if (! HASH_TABLE_P (read_objects_completed) |
| 2549 | || XHASH_TABLE (read_objects_completed)->count) | 2549 | || XHASH_TABLE (read_objects_completed)->count) |
| 2550 | read_objects_completed | 2550 | read_objects_completed |
| 2551 | = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, Weak_None, false); | 2551 | = make_hash_table (&hashtest_eq, DEFAULT_HASH_SIZE, Weak_None, false); |
| 2552 | if (!NILP (Vpurify_flag) && c == '(') | 2552 | if (!NILP (Vpurify_flag) && c == '(') |
| 2553 | val = read0 (readcharfun, false); | 2553 | val = read0 (readcharfun, false); |
| 2554 | else | 2554 | else |
| @@ -2792,11 +2792,11 @@ read_internal_start (Lisp_Object stream, Lisp_Object start, Lisp_Object end, | |||
| 2792 | if (! HASH_TABLE_P (read_objects_map) | 2792 | if (! HASH_TABLE_P (read_objects_map) |
| 2793 | || XHASH_TABLE (read_objects_map)->count) | 2793 | || XHASH_TABLE (read_objects_map)->count) |
| 2794 | read_objects_map | 2794 | read_objects_map |
| 2795 | = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, Weak_None, false); | 2795 | = make_hash_table (&hashtest_eq, DEFAULT_HASH_SIZE, Weak_None, false); |
| 2796 | if (! HASH_TABLE_P (read_objects_completed) | 2796 | if (! HASH_TABLE_P (read_objects_completed) |
| 2797 | || XHASH_TABLE (read_objects_completed)->count) | 2797 | || XHASH_TABLE (read_objects_completed)->count) |
| 2798 | read_objects_completed | 2798 | read_objects_completed |
| 2799 | = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, Weak_None, false); | 2799 | = make_hash_table (&hashtest_eq, DEFAULT_HASH_SIZE, Weak_None, false); |
| 2800 | 2800 | ||
| 2801 | if (STRINGP (stream) | 2801 | if (STRINGP (stream) |
| 2802 | || ((CONSP (stream) && STRINGP (XCAR (stream))))) | 2802 | || ((CONSP (stream) && STRINGP (XCAR (stream))))) |
diff --git a/src/pdumper.c b/src/pdumper.c index 6b053c5b601..13077526776 100644 --- a/src/pdumper.c +++ b/src/pdumper.c | |||
| @@ -2704,7 +2704,8 @@ hash_table_freeze (struct Lisp_Hash_Table *h) | |||
| 2704 | h->index = NULL; | 2704 | h->index = NULL; |
| 2705 | h->table_size = 0; | 2705 | h->table_size = 0; |
| 2706 | h->index_size = 0; | 2706 | h->index_size = 0; |
| 2707 | h->frozen_test = hash_table_std_test (&h->test); | 2707 | h->frozen_test = hash_table_std_test (h->test); |
| 2708 | h->test = NULL; | ||
| 2708 | } | 2709 | } |
| 2709 | 2710 | ||
| 2710 | static dump_off | 2711 | static dump_off |
diff --git a/src/pgtkterm.c b/src/pgtkterm.c index 57ea82daa5e..b731f52983d 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c | |||
| @@ -7178,7 +7178,7 @@ If set to a non-float value, there will be no wait at all. */); | |||
| 7178 | 7178 | ||
| 7179 | DEFVAR_LISP ("pgtk-keysym-table", Vpgtk_keysym_table, | 7179 | DEFVAR_LISP ("pgtk-keysym-table", Vpgtk_keysym_table, |
| 7180 | doc: /* Hash table of character codes indexed by X keysym codes. */); | 7180 | doc: /* Hash table of character codes indexed by X keysym codes. */); |
| 7181 | Vpgtk_keysym_table = make_hash_table (hashtest_eql, 900, Weak_None, false); | 7181 | Vpgtk_keysym_table = make_hash_table (&hashtest_eql, 900, Weak_None, false); |
| 7182 | 7182 | ||
| 7183 | window_being_scrolled = Qnil; | 7183 | window_being_scrolled = Qnil; |
| 7184 | staticpro (&window_being_scrolled); | 7184 | staticpro (&window_being_scrolled); |
diff --git a/src/print.c b/src/print.c index c27c66ae40a..58a23b79d5d 100644 --- a/src/print.c +++ b/src/print.c | |||
| @@ -2577,10 +2577,10 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) | |||
| 2577 | #s(hash-table test equal data (k1 v1 k2 v2)) */ | 2577 | #s(hash-table test equal data (k1 v1 k2 v2)) */ |
| 2578 | print_c_string ("#s(hash-table", printcharfun); | 2578 | print_c_string ("#s(hash-table", printcharfun); |
| 2579 | 2579 | ||
| 2580 | if (!BASE_EQ (h->test.name, Qeql)) | 2580 | if (!BASE_EQ (h->test->name, Qeql)) |
| 2581 | { | 2581 | { |
| 2582 | print_c_string (" test ", printcharfun); | 2582 | print_c_string (" test ", printcharfun); |
| 2583 | print_object (h->test.name, printcharfun, escapeflag); | 2583 | print_object (h->test->name, printcharfun, escapeflag); |
| 2584 | } | 2584 | } |
| 2585 | 2585 | ||
| 2586 | if (h->weakness != Weak_None) | 2586 | if (h->weakness != Weak_None) |
diff --git a/src/profiler.c b/src/profiler.c index 06ffecf41e3..5a6a8b48f6b 100644 --- a/src/profiler.c +++ b/src/profiler.c | |||
| @@ -563,7 +563,7 @@ export_log (struct profiler_log *plog) | |||
| 563 | which is more discriminating than the `function-equal' used by | 563 | which is more discriminating than the `function-equal' used by |
| 564 | the log but close enough, and will never confuse two distinct | 564 | the log but close enough, and will never confuse two distinct |
| 565 | keys in the log. */ | 565 | keys in the log. */ |
| 566 | Lisp_Object h = make_hash_table (hashtest_equal, DEFAULT_HASH_SIZE, | 566 | Lisp_Object h = make_hash_table (&hashtest_equal, DEFAULT_HASH_SIZE, |
| 567 | Weak_None, false); | 567 | Weak_None, false); |
| 568 | for (int i = 0; i < log->size; i++) | 568 | for (int i = 0; i < log->size; i++) |
| 569 | { | 569 | { |
diff --git a/src/xfaces.c b/src/xfaces.c index c9dd0f90feb..2ca2c30636c 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -7333,7 +7333,7 @@ only for this purpose. */); | |||
| 7333 | doc: /* Hash table of global face definitions (for internal use only.) */); | 7333 | doc: /* Hash table of global face definitions (for internal use only.) */); |
| 7334 | Vface_new_frame_defaults = | 7334 | Vface_new_frame_defaults = |
| 7335 | /* 33 entries is enough to fit all basic faces */ | 7335 | /* 33 entries is enough to fit all basic faces */ |
| 7336 | make_hash_table (hashtest_eq, 33, Weak_None, false); | 7336 | make_hash_table (&hashtest_eq, 33, Weak_None, false); |
| 7337 | 7337 | ||
| 7338 | DEFVAR_LISP ("face-default-stipple", Vface_default_stipple, | 7338 | DEFVAR_LISP ("face-default-stipple", Vface_default_stipple, |
| 7339 | doc: /* Default stipple pattern used on monochrome displays. | 7339 | doc: /* Default stipple pattern used on monochrome displays. |
diff --git a/src/xterm.c b/src/xterm.c index e4139a79a6e..77d6550c8b9 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -32554,7 +32554,7 @@ If set to a non-float value, there will be no wait at all. */); | |||
| 32554 | 32554 | ||
| 32555 | DEFVAR_LISP ("x-keysym-table", Vx_keysym_table, | 32555 | DEFVAR_LISP ("x-keysym-table", Vx_keysym_table, |
| 32556 | doc: /* Hash table of character codes indexed by X keysym codes. */); | 32556 | doc: /* Hash table of character codes indexed by X keysym codes. */); |
| 32557 | Vx_keysym_table = make_hash_table (hashtest_eql, 900, Weak_None, false); | 32557 | Vx_keysym_table = make_hash_table (&hashtest_eql, 900, Weak_None, false); |
| 32558 | 32558 | ||
| 32559 | DEFVAR_BOOL ("x-frame-normalize-before-maximize", | 32559 | DEFVAR_BOOL ("x-frame-normalize-before-maximize", |
| 32560 | x_frame_normalize_before_maximize, | 32560 | x_frame_normalize_before_maximize, |