aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreaCorallo2020-02-25 22:35:02 +0000
committerAndrea Corallo2020-02-26 10:40:29 +0000
commit94dcb69256a0daea2c51540217c3abdc2fd50552 (patch)
tree12fd007e8e632f411a7db59f7548969cc8109351 /src
parentf0daf1292ccfd6f07b8ded28e29f01919c43022e (diff)
downloademacs-94dcb69256a0daea2c51540217c3abdc2fd50552.tar.gz
emacs-94dcb69256a0daea2c51540217c3abdc2fd50552.zip
Add ephemeral relocation data class
Add a new class of relocated objects that is in use just during load process. This in order to avoid having to maintain them in the heap and traverse them at every GC.
Diffstat (limited to 'src')
-rw-r--r--src/comp.c78
1 files changed, 62 insertions, 16 deletions
diff --git a/src/comp.c b/src/comp.c
index 2f24b10bba0..b6de0ece36a 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -40,11 +40,13 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
40#define PURE_RELOC_SYM "pure_reloc" 40#define PURE_RELOC_SYM "pure_reloc"
41#define DATA_RELOC_SYM "d_reloc" 41#define DATA_RELOC_SYM "d_reloc"
42#define DATA_RELOC_IMPURE_SYM "d_reloc_imp" 42#define DATA_RELOC_IMPURE_SYM "d_reloc_imp"
43#define DATA_RELOC_EPHEMERAL_SYM "d_reloc_eph"
43#define FUNC_LINK_TABLE_SYM "freloc_link_table" 44#define FUNC_LINK_TABLE_SYM "freloc_link_table"
44#define LINK_TABLE_HASH_SYM "freloc_hash" 45#define LINK_TABLE_HASH_SYM "freloc_hash"
45#define COMP_UNIT_SYM "comp_unit" 46#define COMP_UNIT_SYM "comp_unit"
46#define TEXT_DATA_RELOC_SYM "text_data_reloc" 47#define TEXT_DATA_RELOC_SYM "text_data_reloc"
47#define TEXT_DATA_RELOC_IMPURE_SYM "text_data_reloc_imp" 48#define TEXT_DATA_RELOC_IMPURE_SYM "text_data_reloc_imp"
49#define TEXT_DATA_RELOC_EPHEMERAL_SYM "text_data_reloc_eph"
48 50
49#define SPEED XFIXNUM (Fsymbol_value (Qcomp_speed)) 51#define SPEED XFIXNUM (Fsymbol_value (Qcomp_speed))
50#define COMP_DEBUG XFIXNUM (Fsymbol_value (Qcomp_debug)) 52#define COMP_DEBUG XFIXNUM (Fsymbol_value (Qcomp_debug))
@@ -178,6 +180,8 @@ typedef struct {
178 gcc_jit_rvalue *data_relocs; 180 gcc_jit_rvalue *data_relocs;
179 /* Same as before but can't go in pure space. */ 181 /* Same as before but can't go in pure space. */
180 gcc_jit_rvalue *data_relocs_impure; 182 gcc_jit_rvalue *data_relocs_impure;
183 /* Same as before but content does not survive load phase. */
184 gcc_jit_rvalue *data_relocs_ephemeral;
181 /* Synthesized struct holding func relocs. */ 185 /* Synthesized struct holding func relocs. */
182 gcc_jit_lvalue *func_relocs; 186 gcc_jit_lvalue *func_relocs;
183} comp_t; 187} comp_t;
@@ -382,6 +386,20 @@ register_emitter (Lisp_Object key, void *func)
382 Fputhash (key, value, comp.emitter_dispatcher); 386 Fputhash (key, value, comp.emitter_dispatcher);
383} 387}
384 388
389static gcc_jit_rvalue *
390alloc_class_to_reloc (Lisp_Object alloc_class)
391{
392 if (alloc_class == Qd_base)
393 return comp.data_relocs;
394 else if (alloc_class == Qd_impure)
395 return comp.data_relocs_impure;
396 else if (alloc_class == Qd_ephemeral)
397 return comp.data_relocs_ephemeral;
398 xsignal (Qnative_ice,
399 build_string ("inconsistent allocation class"));
400 assume (false);
401}
402
385static void 403static void
386emit_comment (const char *str) 404emit_comment (const char *str)
387{ 405{
@@ -893,7 +911,7 @@ emit_make_fixnum (gcc_jit_rvalue *obj)
893} 911}
894 912
895static gcc_jit_rvalue * 913static gcc_jit_rvalue *
896emit_const_lisp_obj (Lisp_Object obj, Lisp_Object impure) 914emit_const_lisp_obj (Lisp_Object obj, Lisp_Object alloc_class)
897{ 915{
898 emit_comment (format_string ("const lisp obj: %s", 916 emit_comment (format_string ("const lisp obj: %s",
899 SSDATA (Fprin1_to_string (obj, Qnil)))); 917 SSDATA (Fprin1_to_string (obj, Qnil))));
@@ -904,8 +922,7 @@ emit_const_lisp_obj (Lisp_Object obj, Lisp_Object impure)
904 comp.void_ptr_type, 922 comp.void_ptr_type,
905 NULL)); 923 NULL));
906 924
907 Lisp_Object container = impure ? CALL1I (comp-ctxt-d-impure, Vcomp_ctxt) 925 Lisp_Object container = CALL1I (comp-alloc-class-to-container, alloc_class);
908 : CALL1I (comp-ctxt-d-base, Vcomp_ctxt);
909 Lisp_Object reloc_idx = 926 Lisp_Object reloc_idx =
910 Fgethash (obj, CALL1I (comp-data-container-idx, container), Qnil); 927 Fgethash (obj, CALL1I (comp-data-container-idx, container), Qnil);
911 eassert (!NILP (reloc_idx)); 928 eassert (!NILP (reloc_idx));
@@ -917,8 +934,7 @@ emit_const_lisp_obj (Lisp_Object obj, Lisp_Object impure)
917 gcc_jit_lvalue_as_rvalue ( 934 gcc_jit_lvalue_as_rvalue (
918 gcc_jit_context_new_array_access (comp.ctxt, 935 gcc_jit_context_new_array_access (comp.ctxt,
919 NULL, 936 NULL,
920 impure ? comp.data_relocs_impure 937 alloc_class_to_reloc (alloc_class),
921 : comp.data_relocs,
922 reloc_n)); 938 reloc_n));
923} 939}
924 940
@@ -926,7 +942,7 @@ static gcc_jit_rvalue *
926emit_NILP (gcc_jit_rvalue *x) 942emit_NILP (gcc_jit_rvalue *x)
927{ 943{
928 emit_comment ("NILP"); 944 emit_comment ("NILP");
929 return emit_EQ (x, emit_const_lisp_obj (Qnil, Qnil)); 945 return emit_EQ (x, emit_const_lisp_obj (Qnil, Qd_base));
930} 946}
931 947
932static gcc_jit_rvalue * 948static gcc_jit_rvalue *
@@ -1029,7 +1045,7 @@ emit_CHECK_CONS (gcc_jit_rvalue *x)
1029 1045
1030 gcc_jit_rvalue *args[] = 1046 gcc_jit_rvalue *args[] =
1031 { emit_CONSP (x), 1047 { emit_CONSP (x),
1032 emit_const_lisp_obj (Qconsp, Qnil), 1048 emit_const_lisp_obj (Qconsp, Qd_base),
1033 x }; 1049 x };
1034 1050
1035 gcc_jit_block_add_eval ( 1051 gcc_jit_block_add_eval (
@@ -1140,7 +1156,8 @@ emit_mvar_val (Lisp_Object mvar)
1140 return emit_cast (comp.lisp_obj_type, word); 1156 return emit_cast (comp.lisp_obj_type, word);
1141 } 1157 }
1142 /* Other const objects are fetched from the reloc array. */ 1158 /* Other const objects are fetched from the reloc array. */
1143 return emit_const_lisp_obj (constant, CALL1I (comp-mvar-impure, mvar)); 1159 return emit_const_lisp_obj (constant,
1160 CALL1I (comp-mvar-alloc-class, mvar));
1144 } 1161 }
1145 1162
1146 return gcc_jit_lvalue_as_rvalue (emit_mvar_access (mvar)); 1163 return gcc_jit_lvalue_as_rvalue (emit_mvar_access (mvar));
@@ -1175,7 +1192,7 @@ emit_set_internal (Lisp_Object args)
1175 gcc_jit_rvalue *gcc_args[4]; 1192 gcc_jit_rvalue *gcc_args[4];
1176 FOR_EACH_TAIL (args) 1193 FOR_EACH_TAIL (args)
1177 gcc_args[i++] = emit_mvar_val (XCAR (args)); 1194 gcc_args[i++] = emit_mvar_val (XCAR (args));
1178 gcc_args[2] = emit_const_lisp_obj (Qnil, Qnil); 1195 gcc_args[2] = emit_const_lisp_obj (Qnil, Qd_base);
1179 gcc_args[3] = gcc_jit_context_new_rvalue_from_int (comp.ctxt, 1196 gcc_args[3] = gcc_jit_context_new_rvalue_from_int (comp.ctxt,
1180 comp.int_type, 1197 comp.int_type,
1181 SET_INTERNAL_SET); 1198 SET_INTERNAL_SET);
@@ -1563,7 +1580,9 @@ emit_limple_insn (Lisp_Object insn)
1563 gcc_jit_lvalue_as_rvalue ( 1580 gcc_jit_lvalue_as_rvalue (
1564 gcc_jit_context_new_array_access (comp.ctxt, 1581 gcc_jit_context_new_array_access (comp.ctxt,
1565 NULL, 1582 NULL,
1566 comp.data_relocs, 1583 alloc_class_to_reloc (
1584 CALL1I (comp-mvar-alloc-class,
1585 arg[0])),
1567 reloc_n))); 1586 reloc_n)));
1568 } 1587 }
1569 else if (EQ (op, Qcomment)) 1588 else if (EQ (op, Qcomment))
@@ -1825,6 +1844,10 @@ declare_imported_data (void)
1825 declare_imported_data_relocs (CALL1I (comp-ctxt-d-impure, Vcomp_ctxt), 1844 declare_imported_data_relocs (CALL1I (comp-ctxt-d-impure, Vcomp_ctxt),
1826 DATA_RELOC_IMPURE_SYM, 1845 DATA_RELOC_IMPURE_SYM,
1827 TEXT_DATA_RELOC_IMPURE_SYM); 1846 TEXT_DATA_RELOC_IMPURE_SYM);
1847 comp.data_relocs_ephemeral =
1848 declare_imported_data_relocs (CALL1I (comp-ctxt-d-ephemeral, Vcomp_ctxt),
1849 DATA_RELOC_EPHEMERAL_SYM,
1850 TEXT_DATA_RELOC_EPHEMERAL_SYM);
1828} 1851}
1829 1852
1830/* 1853/*
@@ -2417,11 +2440,11 @@ define_CAR_CDR (void)
2417 comp.block = is_nil_b; 2440 comp.block = is_nil_b;
2418 gcc_jit_block_end_with_return (comp.block, 2441 gcc_jit_block_end_with_return (comp.block,
2419 NULL, 2442 NULL,
2420 emit_const_lisp_obj (Qnil, Qnil)); 2443 emit_const_lisp_obj (Qnil, Qd_base));
2421 2444
2422 comp.block = not_nil_b; 2445 comp.block = not_nil_b;
2423 gcc_jit_rvalue *wrong_type_args[] = 2446 gcc_jit_rvalue *wrong_type_args[] =
2424 { emit_const_lisp_obj (Qlistp, Qnil), c }; 2447 { emit_const_lisp_obj (Qlistp, Qd_base), c };
2425 2448
2426 gcc_jit_block_add_eval (comp.block, 2449 gcc_jit_block_add_eval (comp.block,
2427 NULL, 2450 NULL,
@@ -2430,7 +2453,7 @@ define_CAR_CDR (void)
2430 false)); 2453 false));
2431 gcc_jit_block_end_with_return (comp.block, 2454 gcc_jit_block_end_with_return (comp.block,
2432 NULL, 2455 NULL,
2433 emit_const_lisp_obj (Qnil, Qnil)); 2456 emit_const_lisp_obj (Qnil, Qd_base));
2434 } 2457 }
2435 comp.car = func[0]; 2458 comp.car = func[0];
2436 comp.cdr = func[1]; 2459 comp.cdr = func[1];
@@ -2810,13 +2833,12 @@ define_bool_to_lisp_obj (void)
2810 comp.block = ret_t_block; 2833 comp.block = ret_t_block;
2811 gcc_jit_block_end_with_return (ret_t_block, 2834 gcc_jit_block_end_with_return (ret_t_block,
2812 NULL, 2835 NULL,
2813 emit_const_lisp_obj (Qt, Qnil)); 2836 emit_const_lisp_obj (Qt, Qd_base));
2814 2837
2815 comp.block = ret_nil_block; 2838 comp.block = ret_nil_block;
2816 gcc_jit_block_end_with_return (ret_nil_block, 2839 gcc_jit_block_end_with_return (ret_nil_block,
2817 NULL, 2840 NULL,
2818 emit_const_lisp_obj (Qnil, Qnil)); 2841 emit_const_lisp_obj (Qnil, Qd_base));
2819
2820} 2842}
2821 2843
2822/* Declare a function being compiled and add it to comp.exported_funcs_h. */ 2844/* Declare a function being compiled and add it to comp.exported_funcs_h. */
@@ -3358,12 +3380,25 @@ load_comp_unit (struct Lisp_Native_Comp_Unit *comp_u, bool loading_dump)
3358 EMACS_INT ***pure_reloc = dynlib_sym (handle, PURE_RELOC_SYM); 3380 EMACS_INT ***pure_reloc = dynlib_sym (handle, PURE_RELOC_SYM);
3359 Lisp_Object *data_relocs = dynlib_sym (handle, DATA_RELOC_SYM); 3381 Lisp_Object *data_relocs = dynlib_sym (handle, DATA_RELOC_SYM);
3360 Lisp_Object *data_imp_relocs = dynlib_sym (handle, DATA_RELOC_IMPURE_SYM); 3382 Lisp_Object *data_imp_relocs = dynlib_sym (handle, DATA_RELOC_IMPURE_SYM);
3383 Lisp_Object *data_eph_relocs =
3384 dynlib_sym (handle, DATA_RELOC_EPHEMERAL_SYM);
3361 void **freloc_link_table = dynlib_sym (handle, FUNC_LINK_TABLE_SYM); 3385 void **freloc_link_table = dynlib_sym (handle, FUNC_LINK_TABLE_SYM);
3386 Lisp_Object volatile data_ephemeral_vec;
3387
3388 /* Note: data_ephemeral_vec is not GC protected except than by
3389 this function frame. After this functions will be
3390 deactivated GC will be free to collect it, but it MUST
3391 survive till 'top_level_run' has finished his job. We store
3392 into the ephemeral allocation class only objects that we know
3393 are necessary exclusively during the first load. Once these
3394 are collected we don't have to maintain them in the heap
3395 forever. */
3362 3396
3363 if (!(current_thread_reloc 3397 if (!(current_thread_reloc
3364 && pure_reloc 3398 && pure_reloc
3365 && data_relocs 3399 && data_relocs
3366 && data_imp_relocs 3400 && data_imp_relocs
3401 && data_eph_relocs
3367 && freloc_link_table 3402 && freloc_link_table
3368 && top_level_run) 3403 && top_level_run)
3369 || NILP (Fstring_equal (load_static_obj (comp_u, LINK_TABLE_HASH_SYM), 3404 || NILP (Fstring_equal (load_static_obj (comp_u, LINK_TABLE_HASH_SYM),
@@ -3382,6 +3417,12 @@ load_comp_unit (struct Lisp_Native_Comp_Unit *comp_u, bool loading_dump)
3382 comp_u->data_vec = load_static_obj (comp_u, TEXT_DATA_RELOC_SYM); 3417 comp_u->data_vec = load_static_obj (comp_u, TEXT_DATA_RELOC_SYM);
3383 comp_u->data_impure_vec = 3418 comp_u->data_impure_vec =
3384 load_static_obj (comp_u, TEXT_DATA_RELOC_IMPURE_SYM); 3419 load_static_obj (comp_u, TEXT_DATA_RELOC_IMPURE_SYM);
3420 data_ephemeral_vec =
3421 load_static_obj (comp_u, TEXT_DATA_RELOC_EPHEMERAL_SYM);
3422
3423 EMACS_INT d_vec_len = XFIXNUM (Flength (data_ephemeral_vec));
3424 for (EMACS_INT i = 0; i < d_vec_len; i++)
3425 data_eph_relocs[i] = AREF (data_ephemeral_vec, i);
3385 3426
3386 if (!NILP (Vpurify_flag)) 3427 if (!NILP (Vpurify_flag))
3387 /* Non impure can be copied into pure space. */ 3428 /* Non impure can be copied into pure space. */
@@ -3512,6 +3553,11 @@ syms_of_comp (void)
3512 DEFSYM (Qnumberp, "numberp"); 3553 DEFSYM (Qnumberp, "numberp");
3513 DEFSYM (Qintegerp, "integerp"); 3554 DEFSYM (Qintegerp, "integerp");
3514 3555
3556 /* Allocation classes. */
3557 DEFSYM (Qd_base, "d-base");
3558 DEFSYM (Qd_impure, "d-impure");
3559 DEFSYM (Qd_ephemeral, "d-ephemeral");
3560
3515 /* Others. */ 3561 /* Others. */
3516 DEFSYM (Qfixnum, "fixnum"); 3562 DEFSYM (Qfixnum, "fixnum");
3517 DEFSYM (Qscratch, "scratch"); 3563 DEFSYM (Qscratch, "scratch");