[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
purecopy_hash_table.patch
Description: Text Data
- [PATCH] Make purecopy create hash tables properly,
Vibhav Pant <=