]> git.eshelyaron.com Git - emacs.git/commitdiff
Change HASH_UNUSED_ENTRY_KEY from Qunbound to NULL float
authorMattias EngdegÄrd <mattiase@acm.org>
Fri, 19 Jan 2024 17:31:06 +0000 (18:31 +0100)
committerEshel Yaron <me@eshelyaron.com>
Mon, 22 Jan 2024 16:54:38 +0000 (17:54 +0100)
This removes hacks from code that had to be careful not to use
Qunbound as a hash table key, at the cost of a minor hack in
the GC marker.

* src/lisp.h (INVALID_LISP_VALUE, HASH_UNUSED_ENTRY_KEY):
Define as a null-pointer float.
* src/alloc.c (process_mark_stack): Add hack to ignore that value.
* src/pdumper.c (dump_object_needs_dumping_p)
(pdumper_init_symbol_unbound, pdumper_load):
* src/print.c (PRINT_CIRCLE_CANDIDATE_P): Remove hacks for Qunbound.

(cherry picked from commit 1d754c79603f1b6e4574c7e64c1bf5fb8c6c190d)

src/alloc.c
src/lisp.h
src/pdumper.c
src/print.c

index b78445f65df0a4bacc875e776b7a80dd5bc46cd5..2a1690d2cffeae94f8a986b3d70f28bb90e59922 100644 (file)
@@ -7293,6 +7293,9 @@ process_mark_stack (ptrdiff_t base_sp)
                  struct Lisp_Hash_Table *h = (struct Lisp_Hash_Table *)ptr;
                  set_vector_marked (ptr);
                  if (h->weakness == Weak_None)
+                   /* The values pushed here may include
+                      HASH_UNUSED_ENTRY_KEY, which this function must
+                      cope with.  */
                    mark_stack_push_values (h->key_and_value,
                                            2 * h->table_size);
                  else
@@ -7437,14 +7440,19 @@ process_mark_stack (ptrdiff_t base_sp)
          }
 
        case Lisp_Float:
-         CHECK_ALLOCATED_AND_LIVE (live_float_p, MEM_TYPE_FLOAT);
-         /* Do not mark floats stored in a dump image: these floats are
-            "cold" and do not have mark bits.  */
-         if (pdumper_object_p (XFLOAT (obj)))
-           eassert (pdumper_cold_object_p (XFLOAT (obj)));
-         else if (!XFLOAT_MARKED_P (XFLOAT (obj)))
-           XFLOAT_MARK (XFLOAT (obj));
-         break;
+         {
+           struct Lisp_Float *f = XFLOAT (obj);
+           if (!f)
+             break;            /* for HASH_UNUSED_ENTRY_KEY */
+           CHECK_ALLOCATED_AND_LIVE (live_float_p, MEM_TYPE_FLOAT);
+           /* Do not mark floats stored in a dump image: these floats are
+              "cold" and do not have mark bits.  */
+           if (pdumper_object_p (f))
+             eassert (pdumper_cold_object_p (f));
+           else if (!XFLOAT_MARKED_P (f))
+             XFLOAT_MARK (f);
+           break;
+         }
 
        case_Lisp_Int:
          break;
index edea7cc23bb84df820d404bf6d1f55371c35fc3f..ae78947805e6c9767f9e56688148a8a926d3f296 100644 (file)
@@ -2515,8 +2515,13 @@ struct Lisp_Hash_Table
   struct Lisp_Hash_Table *next_weak;
 } GCALIGNED_STRUCT;
 
+/* A specific Lisp_Object that is not a valid Lisp value.
+   We need to be careful not to leak this value into machinery
+   where it may be treated as one; we'd get a segfault if lucky.  */
+#define INVALID_LISP_VALUE make_lisp_ptr (NULL, Lisp_Float)
+
 /* Key value that marks an unused hash table entry.  */
-#define HASH_UNUSED_ENTRY_KEY Qunbound
+#define HASH_UNUSED_ENTRY_KEY INVALID_LISP_VALUE
 
 /* KEY is a key of an unused hash table entry.  */
 INLINE bool
index 4602931b63ad189a47fdcacd4735f0f871e8e590..8d030585c83c8bb7a3c78e0cbdfba723ce8ab4b9 100644 (file)
@@ -1337,9 +1337,7 @@ dump_object_needs_dumping_p (Lisp_Object object)
      included in the dump despite all references to them being
      bitwise-invariant.  */
   return (!dump_object_self_representing_p (object)
-         || (dump_object_emacs_ptr (object)
-             /* Don't dump Qunbound -- it's not a legal hash table key.  */
-             && !BASE_EQ (object, Qunbound)));
+         || dump_object_emacs_ptr (object));
 }
 
 static void
@@ -2553,19 +2551,6 @@ dump_symbol (struct dump_context *ctx,
   return offset;
 }
 
-/* Give Qunbound its name.
-   All other symbols are dumped and loaded but not Qunbound because it
-   cannot be used as a key in a hash table.
-   FIXME: A better solution would be to use a value other than Qunbound
-   as a marker for unused entries in hash tables.  */
-static void
-pdumper_init_symbol_unbound (void)
-{
-  eassert (NILP (SYMBOL_NAME (Qunbound)));
-  const char *name = "unbound";
-  init_symbol (Qunbound, make_pure_c_string (name, strlen (name)));
-}
-
 static dump_off
 dump_vectorlike_generic (struct dump_context *ctx,
                         const union vectorlike_header *header)
@@ -5767,8 +5752,6 @@ pdumper_load (const char *dump_filename, char *argv0)
   for (int i = 0; i < nr_dump_hooks; ++i)
     dump_hooks[i] ();
 
-  pdumper_init_symbol_unbound ();
-
 #ifdef HAVE_NATIVE_COMP
   pdumper_set_emacs_execdir (argv0);
 #else
index c61fb3cd574512620d5c0419cde6dda0eef0990e..c99d8d5fe3a4e06d3f57ebfeb3064be6df320b11 100644 (file)
@@ -1305,8 +1305,7 @@ print (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
           || RECORDP (obj)))                              \
    || (! NILP (Vprint_gensym)                             \
        && SYMBOLP (obj)                                           \
-       && !SYMBOL_INTERNED_P (obj)                        \
-       && !hash_unused_entry_key_p (obj)))
+       && !SYMBOL_INTERNED_P (obj)))
 
 /* The print preprocess stack, used to traverse data structures.  */
 
@@ -1392,6 +1391,9 @@ static void
 print_preprocess (Lisp_Object obj)
 {
   eassert (!NILP (Vprint_circle));
+  /* The ppstack may contain HASH_UNUSED_ENTRY_KEY which is an invalid
+     Lisp value.  Make sure that our filter stops us from traversing it.  */
+  eassert (!PRINT_CIRCLE_CANDIDATE_P (HASH_UNUSED_ENTRY_KEY));
   ptrdiff_t base_sp = ppstack.sp;
 
   for (;;)
@@ -1450,6 +1452,8 @@ print_preprocess (Lisp_Object obj)
                    if (HASH_TABLE_P (obj))
                      {
                        struct Lisp_Hash_Table *h = XHASH_TABLE (obj);
+                       /* The values pushed here may include
+                          HASH_UNUSED_ENTRY_KEY; see top of this function.  */
                        pp_stack_push_values (h->key_and_value,
                                              2 * h->table_size);
                      }