From 904550d8c8e1583d0444bcb28b5d1130af6bafc3 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Thu, 11 Jun 2020 20:23:00 +0200 Subject: [PATCH] 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 0f7c04129b3..18a2a1ff912 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 507379bf5e6..687e426b1ef 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 -- 2.39.5