aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreaCorallo2020-02-02 15:39:29 +0000
committerAndrea Corallo2020-02-03 12:58:09 +0100
commit6696b561d4d37aebdbb42833d8b5a8d1f4e14482 (patch)
treecda7cfa5ee56b47c3e4afc1bb1811163edfe70c5 /src
parent9e08edf98fdf1a2547eef7b5d9d3debdddb6e7c6 (diff)
downloademacs-6696b561d4d37aebdbb42833d8b5a8d1f4e14482.tar.gz
emacs-6696b561d4d37aebdbb42833d8b5a8d1f4e14482.zip
Fix load_comp_unit for non zero speeds
'dlopen' returns the same handle when trying to load two times the same shared. Touching 'd_reloc' etc leads to fails in case a frame with a reference to it in a register is active. (comp-speed >= 0)
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c19
-rw-r--r--src/comp.c114
-rw-r--r--src/pdumper.c1
3 files changed, 89 insertions, 45 deletions
diff --git a/src/alloc.c b/src/alloc.c
index faa8e703937..431238b13e6 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -517,6 +517,14 @@ Lisp_Object const *staticvec[NSTATICS]
517 517
518int staticidx; 518int staticidx;
519 519
520/* Lisp of freed native compilation unit handles.
521
522 Because during GC Vcomp_loaded_handles can't be used (hash table) temporary
523 annotate here and update Vcomp_loaded_handles when finished.
524*/
525
526static Lisp_Object freed_cu_handles[NATIVE_COMP_FLAG];
527
520static void *pure_alloc (size_t, int); 528static void *pure_alloc (size_t, int);
521 529
522/* Return PTR rounded up to the next multiple of ALIGNMENT. */ 530/* Return PTR rounded up to the next multiple of ALIGNMENT. */
@@ -3030,6 +3038,10 @@ cleanup_vector (struct Lisp_Vector *vector)
3030 PSEUDOVEC_STRUCT (vector, Lisp_Native_Comp_Unit); 3038 PSEUDOVEC_STRUCT (vector, Lisp_Native_Comp_Unit);
3031 eassert (cu->handle); 3039 eassert (cu->handle);
3032 dynlib_close (cu->handle); 3040 dynlib_close (cu->handle);
3041 /* We'll update Vcomp_loaded_handles when finished. */
3042 freed_cu_handles[0] =
3043 Fcons (make_mint_ptr (cu->handle), freed_cu_handles[0]);
3044 set_cons_marked (XCONS (freed_cu_handles[0]));
3033 } 3045 }
3034} 3046}
3035 3047
@@ -5937,6 +5949,9 @@ garbage_collect (void)
5937 if (garbage_collection_messages) 5949 if (garbage_collection_messages)
5938 message1_nolog ("Garbage collecting..."); 5950 message1_nolog ("Garbage collecting...");
5939 5951
5952 if (NATIVE_COMP_FLAG)
5953 freed_cu_handles[0] = Qnil;
5954
5940 block_input (); 5955 block_input ();
5941 5956
5942 shrink_regexp_cache (); 5957 shrink_regexp_cache ();
@@ -6001,6 +6016,10 @@ garbage_collect (void)
6001 6016
6002 gc_in_progress = 0; 6017 gc_in_progress = 0;
6003 6018
6019 if (NATIVE_COMP_FLAG)
6020 FOR_EACH_TAIL (freed_cu_handles[0])
6021 Fputhash (XCAR (freed_cu_handles[0]), Qnil, Vcomp_loaded_handles);
6022
6004 unblock_input (); 6023 unblock_input ();
6005 6024
6006 consing_until_gc = gc_threshold 6025 consing_until_gc = gc_threshold
diff --git a/src/comp.c b/src/comp.c
index 290fc3a9c45..7a1ccdcb83c 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -3282,61 +3282,81 @@ load_static_obj (struct Lisp_Native_Comp_Unit *comp_u, const char *name)
3282void 3282void
3283load_comp_unit (struct Lisp_Native_Comp_Unit *comp_u, bool loading_dump) 3283load_comp_unit (struct Lisp_Native_Comp_Unit *comp_u, bool loading_dump)
3284{ 3284{
3285 freloc_check_fill ();
3286
3287 dynlib_handle_ptr handle = comp_u->handle; 3285 dynlib_handle_ptr handle = comp_u->handle;
3288 struct thread_state ***current_thread_reloc = 3286 Lisp_Object lisp_handle = make_mint_ptr (handle);
3289 dynlib_sym (handle, CURRENT_THREAD_RELOC_SYM); 3287 bool reloading_cu = !NILP (Fgethash (lisp_handle, Vcomp_loaded_handles, Qnil));
3290 EMACS_INT ***pure_reloc = dynlib_sym (handle, PURE_RELOC_SYM); 3288 Lisp_Object comp_u_obj;
3291 Lisp_Object *data_relocs = dynlib_sym (handle, DATA_RELOC_SYM); 3289 XSETNATIVE_COMP_UNIT (comp_u_obj, comp_u);
3292 Lisp_Object *data_imp_relocs = dynlib_sym (handle, DATA_RELOC_IMPURE_SYM); 3290
3293 void **freloc_link_table = dynlib_sym (handle, FUNC_LINK_TABLE_SYM); 3291 if (reloading_cu)
3294 void (*top_level_run)(Lisp_Object) = dynlib_sym (handle, "top_level_run"); 3292 /* 'dlopen' returns the same handle when trying to load two times
3295 3293 the same shared. In this case touching 'd_reloc' etc leads to
3296 if (!(current_thread_reloc 3294 fails in case a frame with a reference to it in a live reg is
3297 && pure_reloc 3295 active (comp-speed >= 0).
3298 && data_relocs 3296
3299 && data_imp_relocs 3297 We must *never* mess with static pointers in an already loaded
3300 && freloc_link_table 3298 eln. */
3301 && top_level_run) 3299 {
3302 || NILP (Fstring_equal (load_static_obj (comp_u, LINK_TABLE_HASH_SYM), 3300 comp_u_obj = Fgethash (lisp_handle, Vcomp_loaded_handles, Qnil);
3303 hash_subr_list ()))) 3301 comp_u = XNATIVE_COMP_UNIT (comp_u_obj);
3304 xsignal1 (Qnative_lisp_file_inconsistent, comp_u->file); 3302 }
3303 else
3304 Fputhash (lisp_handle, comp_u_obj, Vcomp_loaded_handles);
3305 3305
3306 *current_thread_reloc = &current_thread; 3306 freloc_check_fill ();
3307 *pure_reloc = (EMACS_INT **)&pure;
3308 3307
3309 /* Imported functions. */ 3308 void (*top_level_run)(Lisp_Object) = dynlib_sym (handle, "top_level_run");
3310 *freloc_link_table = freloc.link_table;
3311 3309
3312 /* Imported data. */ 3310 if (!reloading_cu)
3313 if (!loading_dump)
3314 { 3311 {
3315 comp_u->data_vec = load_static_obj (comp_u, TEXT_DATA_RELOC_SYM); 3312 struct thread_state ***current_thread_reloc =
3316 comp_u->data_impure_vec = 3313 dynlib_sym (handle, CURRENT_THREAD_RELOC_SYM);
3317 load_static_obj (comp_u, TEXT_DATA_RELOC_IMPURE_SYM); 3314 EMACS_INT ***pure_reloc = dynlib_sym (handle, PURE_RELOC_SYM);
3315 Lisp_Object *data_relocs = dynlib_sym (handle, DATA_RELOC_SYM);
3316 Lisp_Object *data_imp_relocs = dynlib_sym (handle, DATA_RELOC_IMPURE_SYM);
3317 void **freloc_link_table = dynlib_sym (handle, FUNC_LINK_TABLE_SYM);
3318
3319 if (!(current_thread_reloc
3320 && pure_reloc
3321 && data_relocs
3322 && data_imp_relocs
3323 && freloc_link_table
3324 && top_level_run)
3325 || NILP (Fstring_equal (load_static_obj (comp_u, LINK_TABLE_HASH_SYM),
3326 hash_subr_list ())))
3327 xsignal1 (Qnative_lisp_file_inconsistent, comp_u->file);
3328
3329 *current_thread_reloc = &current_thread;
3330 *pure_reloc = (EMACS_INT **)&pure;
3331
3332 /* Imported functions. */
3333 *freloc_link_table = freloc.link_table;
3334
3335 /* Imported data. */
3336 if (!loading_dump)
3337 {
3338 comp_u->data_vec = load_static_obj (comp_u, TEXT_DATA_RELOC_SYM);
3339 comp_u->data_impure_vec =
3340 load_static_obj (comp_u, TEXT_DATA_RELOC_IMPURE_SYM);
3318 3341
3319 if (!NILP (Vpurify_flag)) 3342 if (!NILP (Vpurify_flag))
3320 /* Non impure can be copied into pure space. */ 3343 /* Non impure can be copied into pure space. */
3321 comp_u->data_vec = Fpurecopy (comp_u->data_vec); 3344 comp_u->data_vec = Fpurecopy (comp_u->data_vec);
3322 } 3345 }
3323 3346
3324 EMACS_INT d_vec_len = XFIXNUM (Flength (comp_u->data_vec)); 3347 EMACS_INT d_vec_len = XFIXNUM (Flength (comp_u->data_vec));
3325 for (EMACS_INT i = 0; i < d_vec_len; i++) 3348 for (EMACS_INT i = 0; i < d_vec_len; i++)
3326 data_relocs[i] = AREF (comp_u->data_vec, i); 3349 data_relocs[i] = AREF (comp_u->data_vec, i);
3327 3350
3328 d_vec_len = XFIXNUM (Flength (comp_u->data_impure_vec)); 3351 d_vec_len = XFIXNUM (Flength (comp_u->data_impure_vec));
3329 for (EMACS_INT i = 0; i < d_vec_len; i++) 3352 for (EMACS_INT i = 0; i < d_vec_len; i++)
3330 data_imp_relocs[i] = AREF (comp_u->data_impure_vec, i); 3353 data_imp_relocs[i] = AREF (comp_u->data_impure_vec, i);
3354 }
3331 3355
3332 if (!loading_dump) 3356 if (!loading_dump)
3333 { 3357 /* Executing this will perform all the expected environment
3334 Lisp_Object comp_u_obj; 3358 modifications. */
3335 XSETNATIVE_COMP_UNIT (comp_u_obj, comp_u); 3359 top_level_run (comp_u_obj);
3336 /* Executing this will perform all the expected environment
3337 modifications. */
3338 top_level_run (comp_u_obj);
3339 }
3340 3360
3341 return; 3361 return;
3342} 3362}
@@ -3518,6 +3538,10 @@ syms_of_comp (void)
3518 doc: /* Hash table symbol-function -> function-c-name. For 3538 doc: /* Hash table symbol-function -> function-c-name. For
3519 internal use during */); 3539 internal use during */);
3520 Vcomp_sym_subr_c_name_h = CALLN (Fmake_hash_table); 3540 Vcomp_sym_subr_c_name_h = CALLN (Fmake_hash_table);
3541 DEFVAR_LISP ("comp-loaded-handles", Vcomp_loaded_handles,
3542 doc: /* Hash table keeping track of the currently
3543 loaded compilation unit: handle -> comp_u */);
3544 Vcomp_loaded_handles = CALLN (Fmake_hash_table, QCtest, Qequal);
3521} 3545}
3522 3546
3523#endif /* HAVE_NATIVE_COMP */ 3547#endif /* HAVE_NATIVE_COMP */
diff --git a/src/pdumper.c b/src/pdumper.c
index ae8fe014e0e..8a758499a91 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -5577,6 +5577,7 @@ pdumper_load (const char *dump_filename)
5577 dump_hooks[i] (); 5577 dump_hooks[i] ();
5578 5578
5579 dump_do_all_dump_reloc_for_phase (header, dump_base, LATE_RELOCS); 5579 dump_do_all_dump_reloc_for_phase (header, dump_base, LATE_RELOCS);
5580 Vcomp_loaded_handles = CALLN (Fmake_hash_table, QCtest, Qequal);
5580 dump_do_all_dump_reloc_for_phase (header, dump_base, VERY_LATE_RELOCS); 5581 dump_do_all_dump_reloc_for_phase (header, dump_base, VERY_LATE_RELOCS);
5581 initialized = true; 5582 initialized = true;
5582 5583