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 | |
| 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')
| -rw-r--r-- | src/alloc.c | 19 | ||||
| -rw-r--r-- | src/comp.c | 114 | ||||
| -rw-r--r-- | src/pdumper.c | 1 |
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 | ||
| 518 | int staticidx; | 518 | int 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 | |||
| 526 | static Lisp_Object freed_cu_handles[NATIVE_COMP_FLAG]; | ||
| 527 | |||
| 520 | static void *pure_alloc (size_t, int); | 528 | static 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) | |||
| 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 */ |
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 | ||