emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Make purecopy create hash tables properly


From: Vibhav Pant
Subject: [PATCH] Make purecopy create hash tables properly
Date: Sat, 28 Jan 2017 00:07:05 +0530

As of now, hash tables are purecopied by getting XVECTOR(table),
and copying the contents to pure-alloced memory[0]. This resulted
in purecopy returning a vector consisting of mostly nil and random numbers[1].

As the current lisp code doesn't use printed hash tables anywhere, this
never caused a problem while dumping emacs. However, using printed
hash tables in any code thats loaded in temacs causes the keys and values
of the table to change [2], or segfaults temacs altogether [3].

The following patch attempts to fix this, by adding a make_pure_hash_table
function that returns a copy of the provided Lisp_Hash_Table* value allocated
in pure space. From my testing, this both the issues with printed hash tables
in temacs, although I am not sure about the repercussions of blindly copying
the header (vectorlike_header) from one Lisp_Hash_Table to another. Any
feedback on this would be appreciated, as I would like to get this into master
to continue work on byte-switch [4], which makes use of printed hash tables
in the constant vector of bytecode functions.

I'm not well versed with Emacs internals, apologies if anything above was
incorrect.

[0] http://git.savannah.gnu.org/cgit/emacs.git/tree/src/alloc.c#n5480
[1] http://ix.io/1ReZ
[2] https://lists.gnu.org/archive/html/emacs-devel/2017-01/msg00568.html
[3] https://lists.gnu.org/archive/html/emacs-devel/2017-01/msg00597.html
[4] http://git.savannah.gnu.org/cgit/emacs.git/tree/etc/TODO#n38
---
diff --git a/src/alloc.c b/src/alloc.c
index f7b6515f4e..b64f2de224 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -5434,6 +5434,33 @@ make_pure_vector (ptrdiff_t len)
   return new;
 }

+static struct Lisp_Hash_Table * make_pure_hash_table(struct
Lisp_Hash_Table *table);
+
+/* Return a hash table with the same parameters and values as that of TABLE
+   allocated from pure space.  */
+static struct Lisp_Hash_Table *
+make_pure_hash_table(struct Lisp_Hash_Table *table)
+{
+  struct Lisp_Hash_Table *pure = pure_alloc (sizeof *pure, Lisp_Vectorlike);
+  pure->header = table->header;
+  pure->weak = purecopy (table->weak);
+  pure->rehash_size = purecopy (table->rehash_size);
+  pure->rehash_threshold = purecopy(table->rehash_threshold);
+  pure->hash = purecopy (table->hash);
+  pure->next = purecopy (table->next);
+  pure->next_free = purecopy (table->next_free);
+  pure->index = purecopy (table->index);
+  pure->count = table->count;
+  pure->key_and_value = purecopy (table->key_and_value);
+  pure->test = table->test;
+
+  if (table->next_weak) {
+    pure->next_weak = make_pure_hash_table (table->next_weak);
+  }
+
+  return pure;
+}
+
 DEFUN ("purecopy", Fpurecopy, Spurecopy, 1, 1, 0,
        doc: /* Make a copy of object OBJ in pure storage.
 Recursively copies contents of vectors and cons cells.
@@ -5477,7 +5504,11 @@ purecopy (Lisp_Object obj)
     obj = make_pure_string (SSDATA (obj), SCHARS (obj),
     SBYTES (obj),
     STRING_MULTIBYTE (obj));
-  else if (COMPILEDP (obj) || VECTORP (obj) || HASH_TABLE_P (obj))
+  else if (HASH_TABLE_P (obj)) {
+    struct Lisp_Hash_Table *h = make_pure_hash_table(XHASH_TABLE(obj));
+    XSET_HASH_TABLE(obj, h);
+  }
+  else if (COMPILEDP (obj) || VECTORP (obj))
     {
       struct Lisp_Vector *objp = XVECTOR (obj);
       ptrdiff_t nbytes = vector_nbytes (objp);


-- 
Vibhav Pant
address@hidden

Attachment: purecopy_hash_table.patch
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]