From: Stefan Monnier Date: Wed, 24 Jan 2024 13:07:54 +0000 (-0500) Subject: (DOHASH): Change calling convention X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=6c24990dbdfee4cf672a7f327d1d1a908e5f18a0;p=emacs.git (DOHASH): Change calling convention This leads to simpler code in the users, and more efficient machine code because we don't repeatedly need to fetch the `table_size` and `key_and_value` fields of the hash table object. * src/lisp.h (DOHASH): Rewrite. * src/composite.c (composition_gstring_lookup_cache): Simplify. (composition_gstring_cache_clear_font): * src/print.c (print): * src/pdumper.c (hash_table_contents): * src/minibuf.c (Ftest_completion): * src/json.c (lisp_to_json_nonscalar_1): * src/emacs-module.c (module_global_reference_p): * src/comp.c (compile_function, Fcomp__compile_ctxt_to_file): * src/fns.c (Fmaphash): Adjust to new calling convention. (cherry picked from commit 3018c6e7ba5d35b756aea5eed7f3981548a597b4) --- diff --git a/src/comp.c b/src/comp.c index 25c4cb2f22c..5f28cf046b5 100644 --- a/src/comp.c +++ b/src/comp.c @@ -4330,12 +4330,9 @@ compile_function (Lisp_Object func) declare_block (Qentry); Lisp_Object blocks = CALL1I (comp-func-blocks, func); struct Lisp_Hash_Table *ht = XHASH_TABLE (blocks); - DOHASH (ht, i) - { - Lisp_Object block_name = HASH_KEY (ht, i); - if (!EQ (block_name, Qentry)) - declare_block (block_name); - } + DOHASH (ht, block_name, block) + if (!EQ (block_name, Qentry)) + declare_block (block_name); gcc_jit_block_add_assignment (retrive_block (Qentry), NULL, @@ -4343,10 +4340,8 @@ compile_function (Lisp_Object func) gcc_jit_lvalue_as_rvalue (comp.func_relocs)); - DOHASH (ht, i) + DOHASH (ht, block_name, block) { - Lisp_Object block_name = HASH_KEY (ht, i); - Lisp_Object block = HASH_VALUE (ht, i); Lisp_Object insns = CALL1I (comp-block-insns, block); if (NILP (block) || NILP (insns)) xsignal1 (Qnative_ice, @@ -4961,10 +4956,12 @@ DEFUN ("comp--compile-ctxt-to-file", Fcomp__compile_ctxt_to_file, struct Lisp_Hash_Table *func_h = XHASH_TABLE (CALL1I (comp-ctxt-funcs-h, Vcomp_ctxt)); - DOHASH (func_h, i) declare_function (HASH_VALUE (func_h, i)); + DOHASH (func_h, k, v) + declare_function (v); /* Compile all functions. Can't be done before because the relocation structs has to be already defined. */ - DOHASH (func_h, i) compile_function (HASH_VALUE (func_h, i)); + DOHASH (func_h, k, v) + compile_function (v); /* Work around bug#46495 (GCC PR99126). */ #if defined (WIDE_EMACS_INT) \ diff --git a/src/composite.c b/src/composite.c index d9233fe0cc0..0b78a78fa79 100644 --- a/src/composite.c +++ b/src/composite.c @@ -643,10 +643,7 @@ static Lisp_Object gstring_hash_table; Lisp_Object composition_gstring_lookup_cache (Lisp_Object header) { - struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table); - ptrdiff_t i = hash_lookup (h, header); - - return (i >= 0 ? HASH_VALUE (h, i) : Qnil); + return Fgethash (header, gstring_hash_table, Qnil); } Lisp_Object @@ -687,14 +684,9 @@ composition_gstring_cache_clear_font (Lisp_Object font_object) { struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table); - DOHASH (h, i) - { - Lisp_Object k = HASH_KEY (h, i); - Lisp_Object gstring = HASH_VALUE (h, i); - - if (EQ (LGSTRING_FONT (gstring), font_object)) - hash_remove_from_table (h, k); - } + DOHASH (h, k, gstring) + if (EQ (LGSTRING_FONT (gstring), font_object)) + hash_remove_from_table (h, k); } DEFUN ("clear-composition-cache", Fclear_composition_cache, diff --git a/src/emacs-module.c b/src/emacs-module.c index 77dd2b9152c..08db39b0b0d 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c @@ -410,8 +410,8 @@ module_global_reference_p (emacs_value v, ptrdiff_t *n) struct Lisp_Hash_Table *h = XHASH_TABLE (Vmodule_refs_hash); /* Note that we can't use `hash_lookup' because V might be a local reference that's identical to some global reference. */ - DOHASH (h, i) - if (&XMODULE_GLOBAL_REFERENCE (HASH_VALUE (h, i))->value == v) + DOHASH (h, k, val) + if (&XMODULE_GLOBAL_REFERENCE (val)->value == v) return true; /* Only used for debugging, so we don't care about overflow, just make sure the operation is defined. */ diff --git a/src/fns.c b/src/fns.c index f34e069ddbe..859df6748f7 100644 --- a/src/fns.c +++ b/src/fns.c @@ -5617,7 +5617,7 @@ If KEY is not found, return DFLT which defaults to nil. */) (Lisp_Object key, Lisp_Object table, Lisp_Object dflt) { struct Lisp_Hash_Table *h = check_hash_table (table); - ptrdiff_t i = hash_lookup_with_hash (h, key, hash_from_key (h, key)); + ptrdiff_t i = hash_lookup (h, key); return i >= 0 ? HASH_VALUE (h, i) : dflt; } @@ -5662,7 +5662,8 @@ set a new value for KEY, or `remhash' to remove KEY. (Lisp_Object function, Lisp_Object table) { struct Lisp_Hash_Table *h = check_hash_table (table); - DOHASH (h, i) call2 (function, HASH_KEY (h, i), HASH_VALUE (h, i)); + DOHASH (h, k, v) + call2 (function, k, v); return Qnil; } diff --git a/src/json.c b/src/json.c index 5434780ba13..e849ccaf722 100644 --- a/src/json.c +++ b/src/json.c @@ -361,9 +361,8 @@ lisp_to_json_nonscalar_1 (Lisp_Object lisp, json = json_check (json_object ()); count = SPECPDL_INDEX (); record_unwind_protect_ptr (json_release_object, json); - DOHASH (h, i) + DOHASH (h, key, v) { - Lisp_Object key = HASH_KEY (h, i); CHECK_STRING (key); Lisp_Object ekey = json_encode (key); /* We can't specify the length, so the string must be @@ -376,7 +375,7 @@ lisp_to_json_nonscalar_1 (Lisp_Object lisp, wrong_type_argument (Qjson_value_p, lisp); int status = json_object_set_new (json, key_str, - lisp_to_json (HASH_VALUE (h, i), conf)); + lisp_to_json (v, conf)); if (status == -1) { /* A failure can be caused either by an invalid key or diff --git a/src/lisp.h b/src/lisp.h index 09fcd6689bf..82ce367392e 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2598,16 +2598,24 @@ hash_from_key (struct Lisp_Hash_Table *h, Lisp_Object key) return h->test->hashfn (key, h); } -/* Hash table iteration construct (roughly an inlined maphash): - Iterate IDXVAR as index over valid entries of TABLE. +/* Iterate K and V as key and value of valid entries in hash table H. The body may remove the current entry or alter its value slot, but not mutate TABLE in any other way. */ -#define DOHASH(TABLE, IDXVAR) \ - for (ptrdiff_t IDXVAR = 0; IDXVAR < (TABLE)->table_size; IDXVAR++) \ - if (hash_unused_entry_key_p (HASH_KEY (TABLE, IDXVAR))) \ - ; \ +#define DOHASH(h, k, v) \ + for (Lisp_Object *dohash_##k##_##v##_kv = (h)->key_and_value, \ + *dohash_##k##_##v##_end = dohash_##k##_##v##_kv \ + + 2 * HASH_TABLE_SIZE (h), \ + k, v; \ + dohash_##k##_##v##_kv < dohash_##k##_##v##_end \ + && (k = dohash_##k##_##v##_kv[0], \ + v = dohash_##k##_##v##_kv[1], /*maybe unsed*/ (void)v, \ + true); \ + dohash_##k##_##v##_kv += 2) \ + if (hash_unused_entry_key_p (k)) \ + ; \ else + void hash_table_thaw (Lisp_Object hash_table); /* Default size for hash tables if not specified. */ diff --git a/src/minibuf.c b/src/minibuf.c index f3420815d59..2815d5c2834 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -2059,8 +2059,7 @@ If COLLECTION is a function, it is called with three arguments: the values STRING, PREDICATE and `lambda'. */) (Lisp_Object string, Lisp_Object collection, Lisp_Object predicate) { - Lisp_Object tail, tem = Qnil; - ptrdiff_t i = 0; + Lisp_Object tail, tem = Qnil, arg = Qnil; CHECK_STRING (string); @@ -2079,7 +2078,7 @@ the values STRING, PREDICATE and `lambda'. */) SBYTES (string)); if (completion_ignore_case && !SYMBOLP (tem)) { - for (i = ASIZE (collection) - 1; i >= 0; i--) + for (ptrdiff_t i = ASIZE (collection) - 1; i >= 0; i--) { tail = AREF (collection, i); if (SYMBOLP (tail)) @@ -2107,24 +2106,27 @@ the values STRING, PREDICATE and `lambda'. */) else if (HASH_TABLE_P (collection)) { struct Lisp_Hash_Table *h = XHASH_TABLE (collection); - i = hash_lookup (h, string); + ptrdiff_t i = hash_lookup (h, string); if (i >= 0) { tem = HASH_KEY (h, i); + arg = HASH_VALUE (h, i); goto found_matching_key; } else - DOHASH (h, j) + DOHASH (h, k, v) { - i = j; - tem = HASH_KEY (h, i); + tem = k; Lisp_Object strkey = (SYMBOLP (tem) ? Fsymbol_name (tem) : tem); if (!STRINGP (strkey)) continue; if (BASE_EQ (Fcompare_strings (string, Qnil, Qnil, strkey, Qnil, Qnil, completion_ignore_case ? Qt : Qnil), - Qt)) - goto found_matching_key; + Qt)) + { + arg = v; + goto found_matching_key; + } } return Qnil; found_matching_key: ; @@ -2141,7 +2143,7 @@ the values STRING, PREDICATE and `lambda'. */) if (!NILP (predicate)) { return HASH_TABLE_P (collection) - ? call2 (predicate, tem, HASH_VALUE (XHASH_TABLE (collection), i)) + ? call2 (predicate, tem, arg) : call1 (predicate, tem); } else diff --git a/src/pdumper.c b/src/pdumper.c index 9c9a1ff382c..7f1a78b4f2d 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -2655,10 +2655,10 @@ hash_table_contents (struct Lisp_Hash_Table *h) indices to stay constant across the dump. FIXME: Remove such dependency on hash table internals (there might be another one in `composition_gstring_from_id`). */ - DOHASH (h, i) + DOHASH (h, k, v) { - key_and_value[n++] = HASH_KEY (h, i); - key_and_value[n++] = HASH_VALUE (h, i); + key_and_value[n++] = k; + key_and_value[n++] = v; } return key_and_value; diff --git a/src/print.c b/src/print.c index c99d8d5fe3a..c6a3dba3163 100644 --- a/src/print.c +++ b/src/print.c @@ -1285,9 +1285,9 @@ print (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) { /* Remove unnecessary objects, which appear only once in OBJ; that is, whose status is Qt. */ struct Lisp_Hash_Table *h = XHASH_TABLE (Vprint_number_table); - DOHASH (h, i) - if (EQ (HASH_VALUE (h, i), Qt)) - Fremhash (HASH_KEY (h, i), Vprint_number_table); + DOHASH (h, k, v) + if (EQ (v, Qt)) + Fremhash (k, Vprint_number_table); } }