]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix recursive load for non cons hashed 'data_ephemeral_vec' content
authorAndrea Corallo <akrl@sdf.org>
Thu, 11 Jun 2020 18:23:00 +0000 (20:23 +0200)
committerAndrea Corallo <akrl@sdf.org>
Thu, 11 Jun 2020 16:37:37 +0000 (18:37 +0200)
Removing `Vcomp_sym_subr_c_name_h' all c_name functions are GC
markable only through 'data_ephemeral_vec'.  A recursive load must not
overide its content otherwise a previously activated load will have
the original content collected before it's used.

* src/comp.h (struct Lisp_Native_Comp_Unit): Add 'load_ongoing'
field.

* src/comp.c (unset_cu_load_ongoing): New function.
(load_comp_unit): Update logic to detect and handle recursive
loads.

src/comp.c
src/comp.h

index 0f7c04129b352830b23b74ae252d7fd1ca1b507d..18a2a1ff912e366a81b3c57463074fd5b6fb4152 100644 (file)
@@ -4398,6 +4398,12 @@ check_comp_unit_relocs (struct Lisp_Native_Comp_Unit *comp_u)
   return true;
 }
 
+static void
+unset_cu_load_ongoing (Lisp_Object comp_u)
+{
+  XNATIVE_COMP_UNIT (comp_u)->load_ongoing = false;
+}
+
 void
 load_comp_unit (struct Lisp_Native_Comp_Unit *comp_u, bool loading_dump,
                bool late_load)
@@ -4433,6 +4439,14 @@ load_comp_unit (struct Lisp_Native_Comp_Unit *comp_u, bool loading_dump,
   else
     *saved_cu = comp_u_lisp_obj;
 
+  /* Once we are sure to have the right compilation unit we want to
+     identify is we have at least another load active on it.  */
+  bool recursive_load = comp_u->load_ongoing;
+  comp_u->load_ongoing = true;
+  ptrdiff_t count = SPECPDL_INDEX ();
+  if (!recursive_load)
+    record_unwind_protect (unset_cu_load_ongoing, comp_u_lisp_obj);
+
   freloc_check_fill ();
 
   Lisp_Object (*top_level_run)(Lisp_Object)
@@ -4508,14 +4522,21 @@ load_comp_unit (struct Lisp_Native_Comp_Unit *comp_u, bool loading_dump,
         are necessary exclusively during the first load.  Once these
         are collected we don't have to maintain them in the heap
         forever.  */
+      Lisp_Object volatile data_ephemeral_vec;
+      /* In case another load of the same CU is active on the stack
+        all ephemeral data is hold by that frame.  Re-writing
+        'data_ephemeral_vec' would be not only a waste of cycles but
+        more importanly would lead to crashed if the contained data
+        is not cons hashed.  */
+      if (!recursive_load)
+       {
+         Lisp_Object volatile data_ephemeral_vec  =
+           load_static_obj (comp_u, TEXT_DATA_RELOC_EPHEMERAL_SYM);
 
-      Lisp_Object volatile data_ephemeral_vec  =
-       load_static_obj (comp_u, TEXT_DATA_RELOC_EPHEMERAL_SYM);
-
-      EMACS_INT d_vec_len = XFIXNUM (Flength (data_ephemeral_vec));
-      for (EMACS_INT i = 0; i < d_vec_len; i++)
-       data_eph_relocs[i] = AREF (data_ephemeral_vec, i);
-
+         EMACS_INT d_vec_len = XFIXNUM (Flength (data_ephemeral_vec));
+         for (EMACS_INT i = 0; i < d_vec_len; i++)
+           data_eph_relocs[i] = AREF (data_ephemeral_vec, i);
+       }
       /* Executing this will perform all the expected environment
         modifications.  */
       top_level_run (comp_u_lisp_obj);
@@ -4525,6 +4546,10 @@ load_comp_unit (struct Lisp_Native_Comp_Unit *comp_u, bool loading_dump,
       eassert (check_comp_unit_relocs (comp_u));
     }
 
+  if (!recursive_load)
+    /* Clean-up the load ongoing flag in case.  */
+    unbind_to (count, Qnil);
+
   return;
 }
 
index 507379bf5e6fa7fb4beb705d25860da50f1a8183..687e426b1ef789714882a1d48084c0f91a1b8b53 100644 (file)
@@ -52,7 +52,7 @@ struct Lisp_Native_Comp_Unit
   /* STUFFS WE DO NOT DUMP!!  */
   Lisp_Object *data_imp_relocs;
   bool loaded_once;
-
+  bool load_ongoing;
   dynlib_handle_ptr handle;
 #ifdef WINDOWSNT
   /* We need to store a copy of the original file name in memory that