emacs-diffs
[Top][All Lists]
Advanced

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

feature/native-comp 904550d 2/4: Fix recursive load for non cons hashed


From: Andrea Corallo
Subject: feature/native-comp 904550d 2/4: Fix recursive load for non cons hashed 'data_ephemeral_vec' content
Date: Thu, 11 Jun 2020 13:33:49 -0400 (EDT)

branch: feature/native-comp
commit 904550d8c8e1583d0444bcb28b5d1130af6bafc3
Author: Andrea Corallo <akrl@sdf.org>
Commit: Andrea Corallo <akrl@sdf.org>

    Fix recursive load for non cons hashed 'data_ephemeral_vec' content
    
    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 | 39 ++++++++++++++++++++++++++++++++-------
 src/comp.h |  2 +-
 2 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/src/comp.c b/src/comp.c
index 0f7c041..18a2a1f 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -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;
 }
 
diff --git a/src/comp.h b/src/comp.h
index 507379b..687e426 100644
--- a/src/comp.h
+++ b/src/comp.h
@@ -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



reply via email to

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