From c3d0cc50faf588479db62e20ceabe044dd89e244 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mattias=20Engdeg=C3=A5rd?= Date: Thu, 26 Oct 2023 17:17:01 +0200 Subject: [PATCH] Remove rehash-threshold and rehash-size struct members These parameters have no visible semantics and are hardly ever used, so just use the default values for all hash tables. This saves memory, shrinks the external representation, and will improve performance. * src/fns.c (std_rehash_size, std_rehash_threshold): New. (hash_index_size): Use std_rehash_threshold. Remove table argument. All callers updated. (make_hash_table): Remove rehash_size and rehash_threshold args. All callers updated. (maybe_resize_hash_table) (Fhash_table_rehash_size, Fhash_table_rehash_threshold): Use std_rehash_size and std_rehash_threshold. (Fmake_hash_table): Ignore :rehash-size and :rehash-threshold args. * src/lisp.h (struct Lisp_Hash_Table): Remove rehash_size and rehash_threshold fields. (DEFAULT_REHASH_THRESHOLD, DEFAULT_REHASH_SIZE): Remove. * src/lread.c (hash_table_from_plist): Don't read rehash-size or rehash-threshold. (syms_of_lread): Remove unused symbols. * src/print.c (print_object): Don't print rehash-size or rehash-threshold. * src/pdumper.c (dump_hash_table): Don't dump removed fields. --- src/category.c | 4 +- src/emacs-module.c | 4 +- src/fns.c | 101 ++++++++++++++------------------------------- src/frame.c | 3 +- src/image.c | 4 +- src/lisp.h | 23 +---------- src/lread.c | 20 +++------ src/pdumper.c | 2 - src/pgtkterm.c | 4 +- src/print.c | 8 ---- src/profiler.c | 2 - src/xfaces.c | 3 +- src/xterm.c | 5 +-- 13 files changed, 43 insertions(+), 140 deletions(-) diff --git a/src/category.c b/src/category.c index 67429e82571..583cdb3eebb 100644 --- a/src/category.c +++ b/src/category.c @@ -51,9 +51,7 @@ hash_get_category_set (Lisp_Object table, Lisp_Object category_set) if (NILP (XCHAR_TABLE (table)->extras[1])) set_char_table_extras (table, 1, - make_hash_table (hashtest_equal, DEFAULT_HASH_SIZE, - DEFAULT_REHASH_SIZE, DEFAULT_REHASH_THRESHOLD, - Weak_None, false)); + make_hash_table (hashtest_equal, DEFAULT_HASH_SIZE, Weak_None, false)); struct Lisp_Hash_Table *h = XHASH_TABLE (XCHAR_TABLE (table)->extras[1]); Lisp_Object hash; ptrdiff_t i = hash_lookup (h, category_set, &hash); diff --git a/src/emacs-module.c b/src/emacs-module.c index 44c3efd1440..60aed68f2cd 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c @@ -1697,9 +1697,7 @@ syms_of_module (void) { staticpro (&Vmodule_refs_hash); Vmodule_refs_hash - = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, - DEFAULT_REHASH_SIZE, DEFAULT_REHASH_THRESHOLD, - Weak_None, false); + = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, Weak_None, false); DEFSYM (Qmodule_load_failed, "module-load-failed"); Fput (Qmodule_load_failed, Qerror_conditions, diff --git a/src/fns.c b/src/fns.c index 5837795f838..efec74d4959 100644 --- a/src/fns.c +++ b/src/fns.c @@ -4509,11 +4509,17 @@ allocate_hash_table (void) - header_size - GCALIGNMENT) \ / word_size))) +/* Default factor by which to increase the size of a hash table. */ +static const double std_rehash_size = 1.5; + +/* Resize hash table when number of entries / table size is >= this + ratio. */ +static const double std_rehash_threshold = 0.8125; + static ptrdiff_t -hash_index_size (struct Lisp_Hash_Table *h, ptrdiff_t size) +hash_index_size (ptrdiff_t size) { - double threshold = h->rehash_threshold; - double index_float = size / threshold; + double index_float = size * (1.0 / std_rehash_threshold); ptrdiff_t index_size = (index_float < INDEX_SIZE_BOUND + 1 ? next_almost_prime (index_float) : INDEX_SIZE_BOUND + 1); @@ -4531,16 +4537,6 @@ hash_index_size (struct Lisp_Hash_Table *h, ptrdiff_t size) Give the table initial capacity SIZE, 0 <= SIZE <= MOST_POSITIVE_FIXNUM. - If REHASH_SIZE is equal to a negative integer, this hash table's - new size when it becomes full is computed by subtracting - REHASH_SIZE from its old size. Otherwise it must be positive, and - the table's new size is computed by multiplying its old size by - REHASH_SIZE + 1. - - REHASH_THRESHOLD must be a float <= 1.0, and > 0. The table will - be resized when the approximate ratio of table entries to table - size exceeds REHASH_THRESHOLD. - WEAK specifies the weakness of the table. If PURECOPY is non-nil, the table can be copied to pure storage via @@ -4549,7 +4545,6 @@ hash_index_size (struct Lisp_Hash_Table *h, ptrdiff_t size) Lisp_Object make_hash_table (struct hash_table_test test, EMACS_INT size, - float rehash_size, float rehash_threshold, hash_table_weakness_t weak, bool purecopy) { struct Lisp_Hash_Table *h; @@ -4559,8 +4554,6 @@ make_hash_table (struct hash_table_test test, EMACS_INT size, /* Preconditions. */ eassert (SYMBOLP (test.name)); eassert (0 <= size && size <= MOST_POSITIVE_FIXNUM); - eassert (rehash_size <= -1 || 0 < rehash_size); - eassert (0 < rehash_threshold && rehash_threshold <= 1); if (size == 0) size = 1; @@ -4571,13 +4564,11 @@ make_hash_table (struct hash_table_test test, EMACS_INT size, /* Initialize hash table slots. */ h->test = test; h->weakness = weak; - h->rehash_threshold = rehash_threshold; - h->rehash_size = rehash_size; h->count = 0; h->key_and_value = make_vector (2 * size, HASH_UNUSED_ENTRY_KEY); h->hash = make_nil_vector (size); h->next = make_vector (size, make_fixnum (-1)); - h->index = make_vector (hash_index_size (h, size), make_fixnum (-1)); + h->index = make_vector (hash_index_size (size), make_fixnum (-1)); h->next_weak = NULL; h->purecopy = purecopy; h->mutable = true; @@ -4648,18 +4639,12 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h) { ptrdiff_t old_size = HASH_TABLE_SIZE (h); EMACS_INT new_size; - double rehash_size = h->rehash_size; - if (rehash_size < 0) - new_size = old_size - rehash_size; + double float_new_size = old_size * std_rehash_size; + if (float_new_size < EMACS_INT_MAX) + new_size = float_new_size; else - { - double float_new_size = old_size * (rehash_size + 1); - if (float_new_size < EMACS_INT_MAX) - new_size = float_new_size; - else - new_size = EMACS_INT_MAX; - } + new_size = EMACS_INT_MAX; if (PTRDIFF_MAX < new_size) new_size = PTRDIFF_MAX; if (new_size <= old_size) @@ -4682,7 +4667,7 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h) Lisp_Object hash = alloc_larger_vector (h->hash, new_size); memclear (XVECTOR (hash)->contents + old_size, (new_size - old_size) * word_size); - ptrdiff_t index_size = hash_index_size (h, new_size); + ptrdiff_t index_size = hash_index_size (new_size); h->index = make_vector (index_size, make_fixnum (-1)); h->key_and_value = key_and_value; h->hash = hash; @@ -5281,15 +5266,6 @@ keys. Default is `eql'. Predefined are the tests `eq', `eql', and :size SIZE -- A hint as to how many elements will be put in the table. Default is 65. -:rehash-size REHASH-SIZE - Indicates how to expand the table when it -fills up. If REHASH-SIZE is an integer, increase the size by that -amount. If it is a float, it must be > 1.0, and the new size is the -old size multiplied by that factor. Default is 1.5. - -:rehash-threshold THRESHOLD -- THRESHOLD must a float > 0, and <= 1.0. -Resize the hash table when the ratio (table entries / table size) -exceeds an approximation to THRESHOLD. Default is 0.8125. - :weakness WEAK -- WEAK must be one of nil, t, `key', `value', `key-or-value', or `key-and-value'. If WEAK is not nil, the table returned is a weak table. Key/value pairs are removed from a weak @@ -5303,6 +5279,9 @@ to pure storage when Emacs is being dumped, making the contents of the table read only. Any further changes to purified tables will result in an error. +The keywords arguments :rehash-threshold and :rehash-size are obsolete +and ignored. + usage: (make-hash-table &rest KEYWORD-ARGS) */) (ptrdiff_t nargs, Lisp_Object *args) { @@ -5352,26 +5331,6 @@ usage: (make-hash-table &rest KEYWORD-ARGS) */) else signal_error ("Invalid hash table size", size_arg); - /* Look for `:rehash-size SIZE'. */ - float rehash_size; - i = get_key_arg (QCrehash_size, nargs, args, used); - if (!i) - rehash_size = DEFAULT_REHASH_SIZE; - else if (FIXNUMP (args[i]) && 0 < XFIXNUM (args[i])) - rehash_size = - XFIXNUM (args[i]); - else if (FLOATP (args[i]) && 0 < (float) (XFLOAT_DATA (args[i]) - 1)) - rehash_size = (float) (XFLOAT_DATA (args[i]) - 1); - else - signal_error ("Invalid hash table rehash size", args[i]); - - /* Look for `:rehash-threshold THRESHOLD'. */ - i = get_key_arg (QCrehash_threshold, nargs, args, used); - float rehash_threshold = (!i ? DEFAULT_REHASH_THRESHOLD - : !FLOATP (args[i]) ? 0 - : (float) XFLOAT_DATA (args[i])); - if (! (0 < rehash_threshold && rehash_threshold <= 1)) - signal_error ("Invalid hash table rehash threshold", args[i]); - /* Look for `:weakness WEAK'. */ i = get_key_arg (QCweakness, nargs, args, used); Lisp_Object weakness = i ? args[i] : Qnil; @@ -5392,11 +5351,16 @@ usage: (make-hash-table &rest KEYWORD-ARGS) */) /* Now, all args should have been used up, or there's a problem. */ for (i = 0; i < nargs; ++i) if (!used[i]) - signal_error ("Invalid argument list", args[i]); + { + /* Ignore obsolete arguments. */ + if (EQ (args[i], QCrehash_threshold) || EQ (args[i], QCrehash_size)) + i++; + else + signal_error ("Invalid argument list", args[i]); + } SAFE_FREE (); - return make_hash_table (testdesc, size, rehash_size, rehash_threshold, weak, - purecopy); + return make_hash_table (testdesc, size, weak, purecopy); } @@ -5422,14 +5386,8 @@ DEFUN ("hash-table-rehash-size", Fhash_table_rehash_size, doc: /* Return the current rehash size of TABLE. */) (Lisp_Object table) { - double rehash_size = check_hash_table (table)->rehash_size; - if (rehash_size < 0) - { - EMACS_INT s = -rehash_size; - return make_fixnum (min (s, MOST_POSITIVE_FIXNUM)); - } - else - return make_float (rehash_size + 1); + CHECK_HASH_TABLE (table); + return make_float (std_rehash_size); } @@ -5438,7 +5396,8 @@ DEFUN ("hash-table-rehash-threshold", Fhash_table_rehash_threshold, doc: /* Return the current rehash threshold of TABLE. */) (Lisp_Object table) { - return make_float (check_hash_table (table)->rehash_threshold); + CHECK_HASH_TABLE (table); + return make_float (std_rehash_threshold); } diff --git a/src/frame.c b/src/frame.c index 41b0f2f5764..08057736272 100644 --- a/src/frame.c +++ b/src/frame.c @@ -1040,8 +1040,7 @@ make_frame (bool mini_p) rw->pixel_height = rw->total_lines * FRAME_LINE_HEIGHT (f); fset_face_hash_table - (f, make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, DEFAULT_REHASH_SIZE, - DEFAULT_REHASH_THRESHOLD, Weak_None, false)); + (f, make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, Weak_None, false)); if (mini_p) { diff --git a/src/image.c b/src/image.c index 92e1e0b0be7..9c100213590 100644 --- a/src/image.c +++ b/src/image.c @@ -6069,9 +6069,7 @@ xpm_make_color_table_h (void (**put_func) (Lisp_Object, const char *, int, { *put_func = xpm_put_color_table_h; *get_func = xpm_get_color_table_h; - return make_hash_table (hashtest_equal, DEFAULT_HASH_SIZE, - DEFAULT_REHASH_SIZE, DEFAULT_REHASH_THRESHOLD, - Weak_None, false); + return make_hash_table (hashtest_equal, DEFAULT_HASH_SIZE, Weak_None, false); } static void diff --git a/src/lisp.h b/src/lisp.h index 480d963e63d..48e1f943ed8 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2482,17 +2482,6 @@ struct Lisp_Hash_Table immutable for recursive attempts to mutate it. */ bool mutable; - /* Resize hash table when number of entries / table size is >= this - ratio. */ - float rehash_threshold; - - /* Used when the table is resized. If equal to a negative integer, - the user rehash-size is the integer -REHASH_SIZE, and the new - size is the old size plus -REHASH_SIZE. If positive, the user - rehash-size is the floating-point value REHASH_SIZE + 1, and the - new size is the old size times REHASH_SIZE + 1. */ - float rehash_size; - /* Vector of keys and values. The key of item I is found at index 2 * I, the value is found at index 2 * I + 1. If the key is HASH_UNUSED_ENTRY_KEY, then this slot is unused. @@ -2580,16 +2569,6 @@ void hash_table_rehash (Lisp_Object); enum DEFAULT_HASH_SIZE { DEFAULT_HASH_SIZE = 65 }; -/* Default threshold specifying when to resize a hash table. The - value gives the ratio of current entries in the hash table and the - size of the hash table. */ - -static float const DEFAULT_REHASH_THRESHOLD = 0.8125; - -/* Default factor by which to increase the size of a hash table, minus 1. */ - -static float const DEFAULT_REHASH_SIZE = 1.5 - 1; - /* Combine two integers X and Y for hashing. The result might exceed INTMASK. */ @@ -4060,7 +4039,7 @@ extern char *extract_data_from_object (Lisp_Object, ptrdiff_t *, ptrdiff_t *); EMACS_UINT hash_string (char const *, ptrdiff_t); EMACS_UINT sxhash (Lisp_Object); Lisp_Object hashfn_user_defined (Lisp_Object, struct Lisp_Hash_Table *); -Lisp_Object make_hash_table (struct hash_table_test, EMACS_INT, float, float, +Lisp_Object make_hash_table (struct hash_table_test, EMACS_INT, hash_table_weakness_t, bool); Lisp_Object hash_table_weakness_symbol (hash_table_weakness_t weak); ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object *); diff --git a/src/lread.c b/src/lread.c index 6d3c06265e0..284536fc81f 100644 --- a/src/lread.c +++ b/src/lread.c @@ -2544,15 +2544,11 @@ readevalloop (Lisp_Object readcharfun, if (! HASH_TABLE_P (read_objects_map) || XHASH_TABLE (read_objects_map)->count) read_objects_map - = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, - DEFAULT_REHASH_SIZE, DEFAULT_REHASH_THRESHOLD, - Weak_None, false); + = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, Weak_None, false); if (! HASH_TABLE_P (read_objects_completed) || XHASH_TABLE (read_objects_completed)->count) read_objects_completed - = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, - DEFAULT_REHASH_SIZE, DEFAULT_REHASH_THRESHOLD, - Weak_None, false); + = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, Weak_None, false); if (!NILP (Vpurify_flag) && c == '(') val = read0 (readcharfun, false); else @@ -2796,13 +2792,11 @@ read_internal_start (Lisp_Object stream, Lisp_Object start, Lisp_Object end, if (! HASH_TABLE_P (read_objects_map) || XHASH_TABLE (read_objects_map)->count) read_objects_map - = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, DEFAULT_REHASH_SIZE, - DEFAULT_REHASH_THRESHOLD, Weak_None, false); + = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, Weak_None, false); if (! HASH_TABLE_P (read_objects_completed) || XHASH_TABLE (read_objects_completed)->count) read_objects_completed - = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, DEFAULT_REHASH_SIZE, - DEFAULT_REHASH_THRESHOLD, Weak_None, false); + = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, Weak_None, false); if (STRINGP (stream) || ((CONSP (stream) && STRINGP (XCAR (stream))))) @@ -3412,7 +3406,7 @@ read_string_literal (Lisp_Object readcharfun) static Lisp_Object hash_table_from_plist (Lisp_Object plist) { - Lisp_Object params[12]; + Lisp_Object params[4 * 2]; Lisp_Object *par = params; /* This is repetitive but fast and simple. */ @@ -3428,8 +3422,6 @@ hash_table_from_plist (Lisp_Object plist) ADDPARAM (test); ADDPARAM (weakness); - ADDPARAM (rehash_size); - ADDPARAM (rehash_threshold); ADDPARAM (purecopy); Lisp_Object data = plist_get (plist, Qdata); @@ -5998,8 +5990,6 @@ that are loaded before your customizations are read! */); DEFSYM (Qsize, "size"); DEFSYM (Qpurecopy, "purecopy"); DEFSYM (Qweakness, "weakness"); - DEFSYM (Qrehash_size, "rehash-size"); - DEFSYM (Qrehash_threshold, "rehash-threshold"); DEFSYM (Qchar_from_name, "char-from-name"); diff --git a/src/pdumper.c b/src/pdumper.c index 982b991dc63..8072148c542 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -2729,8 +2729,6 @@ dump_hash_table (struct dump_context *ctx, Lisp_Object object) DUMP_FIELD_COPY (out, hash, weakness); DUMP_FIELD_COPY (out, hash, purecopy); DUMP_FIELD_COPY (out, hash, mutable); - DUMP_FIELD_COPY (out, hash, rehash_threshold); - DUMP_FIELD_COPY (out, hash, rehash_size); dump_field_lv (ctx, out, hash, &hash->key_and_value, WEIGHT_STRONG); dump_field_lv (ctx, out, hash, &hash->test.name, WEIGHT_STRONG); dump_field_lv (ctx, out, hash, &hash->test.user_hash_function, diff --git a/src/pgtkterm.c b/src/pgtkterm.c index b45cf56135d..57ea82daa5e 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c @@ -7178,9 +7178,7 @@ If set to a non-float value, there will be no wait at all. */); DEFVAR_LISP ("pgtk-keysym-table", Vpgtk_keysym_table, doc: /* Hash table of character codes indexed by X keysym codes. */); - Vpgtk_keysym_table = make_hash_table (hashtest_eql, 900, DEFAULT_REHASH_SIZE, - DEFAULT_REHASH_THRESHOLD, - Weak_None, false); + Vpgtk_keysym_table = make_hash_table (hashtest_eql, 900, Weak_None, false); window_being_scrolled = Qnil; staticpro (&window_being_scrolled); diff --git a/src/print.c b/src/print.c index 9c361444458..cc8df639f4f 100644 --- a/src/print.c +++ b/src/print.c @@ -2590,14 +2590,6 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) printcharfun, escapeflag); } - print_c_string (" rehash-size ", printcharfun); - print_object (Fhash_table_rehash_size (obj), - printcharfun, escapeflag); - - print_c_string (" rehash-threshold ", printcharfun); - print_object (Fhash_table_rehash_threshold (obj), - printcharfun, escapeflag); - if (h->purecopy) print_c_string (" purecopy t", printcharfun); diff --git a/src/profiler.c b/src/profiler.c index a75998c7c40..06ffecf41e3 100644 --- a/src/profiler.c +++ b/src/profiler.c @@ -564,8 +564,6 @@ export_log (struct profiler_log *plog) the log but close enough, and will never confuse two distinct keys in the log. */ Lisp_Object h = make_hash_table (hashtest_equal, DEFAULT_HASH_SIZE, - DEFAULT_REHASH_SIZE, - DEFAULT_REHASH_THRESHOLD, Weak_None, false); for (int i = 0; i < log->size; i++) { diff --git a/src/xfaces.c b/src/xfaces.c index 7c3dd7ebc15..c9dd0f90feb 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -7333,8 +7333,7 @@ only for this purpose. */); doc: /* Hash table of global face definitions (for internal use only.) */); Vface_new_frame_defaults = /* 33 entries is enough to fit all basic faces */ - make_hash_table (hashtest_eq, 33, DEFAULT_REHASH_SIZE, - DEFAULT_REHASH_THRESHOLD, Weak_None, false); + make_hash_table (hashtest_eq, 33, Weak_None, false); DEFVAR_LISP ("face-default-stipple", Vface_default_stipple, doc: /* Default stipple pattern used on monochrome displays. diff --git a/src/xterm.c b/src/xterm.c index 98f8c8afb3b..e4139a79a6e 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -32554,10 +32554,7 @@ If set to a non-float value, there will be no wait at all. */); DEFVAR_LISP ("x-keysym-table", Vx_keysym_table, doc: /* Hash table of character codes indexed by X keysym codes. */); - Vx_keysym_table = make_hash_table (hashtest_eql, 900, - DEFAULT_REHASH_SIZE, - DEFAULT_REHASH_THRESHOLD, - Weak_None, false); + Vx_keysym_table = make_hash_table (hashtest_eql, 900, Weak_None, false); DEFVAR_BOOL ("x-frame-normalize-before-maximize", x_frame_normalize_before_maximize, -- 2.39.2