diff options
| author | AndreaCorallo | 2020-02-02 15:39:29 +0000 |
|---|---|---|
| committer | Andrea Corallo | 2020-02-03 12:58:09 +0100 |
| commit | 6696b561d4d37aebdbb42833d8b5a8d1f4e14482 (patch) | |
| tree | cda7cfa5ee56b47c3e4afc1bb1811163edfe70c5 /src/comp.c | |
| parent | 9e08edf98fdf1a2547eef7b5d9d3debdddb6e7c6 (diff) | |
| download | emacs-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/comp.c')
| -rw-r--r-- | src/comp.c | 114 |
1 files changed, 69 insertions, 45 deletions
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) | |||
| 3282 | void | 3282 | void |
| 3283 | load_comp_unit (struct Lisp_Native_Comp_Unit *comp_u, bool loading_dump) | 3283 | load_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 = ¤t_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 = ¤t_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 */ |