[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