diff options
| author | Andrea Corallo | 2019-12-14 09:28:12 +0100 |
|---|---|---|
| committer | Andrea Corallo | 2020-01-01 11:38:13 +0100 |
| commit | 694ece772220346aef12520bc66ca401d08809bb (patch) | |
| tree | 01a29820fbb8ab0e2567f47b48b39f010107283b /src | |
| parent | 740462da6153b111a8196b003791a55c7f7fa878 (diff) | |
| download | emacs-694ece772220346aef12520bc66ca401d08809bb.tar.gz emacs-694ece772220346aef12520bc66ca401d08809bb.zip | |
reworking relocation mechanism to use one single table
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp.c | 116 | ||||
| -rw-r--r-- | src/emacs.c | 4 | ||||
| -rw-r--r-- | src/lisp.h | 3 | ||||
| -rw-r--r-- | src/lread.c | 3 |
4 files changed, 81 insertions, 45 deletions
diff --git a/src/comp.c b/src/comp.c index 70b423aa97a..a233187ccdf 100644 --- a/src/comp.c +++ b/src/comp.c | |||
| @@ -70,6 +70,16 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 70 | #endif | 70 | #endif |
| 71 | #define SETJMP_NAME SETJMP | 71 | #define SETJMP_NAME SETJMP |
| 72 | 72 | ||
| 73 | /* Max number function importable by native compiled code. */ | ||
| 74 | #define F_RELOC_MAX_SIZE 1500 | ||
| 75 | |||
| 76 | typedef struct { | ||
| 77 | void *link_table[F_RELOC_MAX_SIZE]; | ||
| 78 | ptrdiff_t size; | ||
| 79 | } f_reloc_t; | ||
| 80 | |||
| 81 | static f_reloc_t freloc; | ||
| 82 | |||
| 73 | /* C side of the compiler context. */ | 83 | /* C side of the compiler context. */ |
| 74 | 84 | ||
| 75 | typedef struct { | 85 | typedef struct { |
| @@ -157,7 +167,7 @@ typedef struct { | |||
| 157 | gcc_jit_function *check_impure; | 167 | gcc_jit_function *check_impure; |
| 158 | Lisp_Object func_blocks_h; /* blk_name -> gcc_block. */ | 168 | Lisp_Object func_blocks_h; /* blk_name -> gcc_block. */ |
| 159 | Lisp_Object exported_funcs_h; /* subr_name -> gcc_jit_function *. */ | 169 | Lisp_Object exported_funcs_h; /* subr_name -> gcc_jit_function *. */ |
| 160 | Lisp_Object imported_funcs_h; /* subr_name -> reloc_field. */ | 170 | Lisp_Object imported_funcs_h; /* subr_name -> gcc_jit_field *reloc_field. */ |
| 161 | Lisp_Object emitter_dispatcher; | 171 | Lisp_Object emitter_dispatcher; |
| 162 | gcc_jit_rvalue *data_relocs; /* Synthesized struct holding data relocs. */ | 172 | gcc_jit_rvalue *data_relocs; /* Synthesized struct holding data relocs. */ |
| 163 | gcc_jit_lvalue *func_relocs; /* Synthesized struct holding func relocs. */ | 173 | gcc_jit_lvalue *func_relocs; /* Synthesized struct holding func relocs. */ |
| @@ -184,6 +194,20 @@ Lisp_Object helper_unbind_n (Lisp_Object n); | |||
| 184 | void helper_save_restriction (void); | 194 | void helper_save_restriction (void); |
| 185 | bool helper_PSEUDOVECTOR_TYPEP_XUNTAG (Lisp_Object a, enum pvec_type code); | 195 | bool helper_PSEUDOVECTOR_TYPEP_XUNTAG (Lisp_Object a, enum pvec_type code); |
| 186 | 196 | ||
| 197 | void *helper_link_table[] = | ||
| 198 | { wrong_type_argument, | ||
| 199 | helper_PSEUDOVECTOR_TYPEP_XUNTAG, | ||
| 200 | pure_write_error, | ||
| 201 | push_handler, | ||
| 202 | SETJMP_NAME, | ||
| 203 | record_unwind_protect_excursion, | ||
| 204 | helper_unbind_n, | ||
| 205 | helper_save_restriction, | ||
| 206 | record_unwind_current_buffer, | ||
| 207 | set_internal, | ||
| 208 | helper_unwind_protect, | ||
| 209 | specbind }; | ||
| 210 | |||
| 187 | 211 | ||
| 188 | static char * ATTRIBUTE_FORMAT_PRINTF (1, 2) | 212 | static char * ATTRIBUTE_FORMAT_PRINTF (1, 2) |
| 189 | format_string (const char *format, ...) | 213 | format_string (const char *format, ...) |
| @@ -1758,7 +1782,7 @@ declare_runtime_imported_funcs (void) | |||
| 1758 | 1782 | ||
| 1759 | #undef ADD_IMPORTED | 1783 | #undef ADD_IMPORTED |
| 1760 | 1784 | ||
| 1761 | return field_list; | 1785 | return Freverse (field_list); |
| 1762 | } | 1786 | } |
| 1763 | 1787 | ||
| 1764 | /* | 1788 | /* |
| @@ -1767,7 +1791,6 @@ declare_runtime_imported_funcs (void) | |||
| 1767 | static void | 1791 | static void |
| 1768 | emit_ctxt_code (void) | 1792 | emit_ctxt_code (void) |
| 1769 | { | 1793 | { |
| 1770 | USE_SAFE_ALLOCA; | ||
| 1771 | 1794 | ||
| 1772 | comp.current_thread_ref = | 1795 | comp.current_thread_ref = |
| 1773 | gcc_jit_lvalue_as_rvalue ( | 1796 | gcc_jit_lvalue_as_rvalue ( |
| @@ -1809,56 +1832,32 @@ emit_ctxt_code (void) | |||
| 1809 | 1832 | ||
| 1810 | emit_static_object (TEXT_DATA_RELOC_SYM, d_reloc); | 1833 | emit_static_object (TEXT_DATA_RELOC_SYM, d_reloc); |
| 1811 | 1834 | ||
| 1812 | /* Imported functions from non Lisp code. */ | 1835 | /* Functions imported from Lisp code. */ |
| 1813 | Lisp_Object f_runtime = declare_runtime_imported_funcs (); | ||
| 1814 | EMACS_INT f_reloc_len = XFIXNUM (Flength (f_runtime)); | ||
| 1815 | |||
| 1816 | /* Imported subrs. */ | ||
| 1817 | Lisp_Object f_subr = CALL1I (comp-ctxt-func-relocs-l, Vcomp_ctxt); | ||
| 1818 | f_reloc_len += XFIXNUM (Flength (f_subr)); | ||
| 1819 | |||
| 1820 | gcc_jit_field **fields = SAFE_ALLOCA (f_reloc_len * sizeof (*fields)); | ||
| 1821 | Lisp_Object f_reloc_list = Qnil; | ||
| 1822 | int n_frelocs = 0; | ||
| 1823 | 1836 | ||
| 1837 | static gcc_jit_field *fields[F_RELOC_MAX_SIZE]; | ||
| 1838 | ptrdiff_t n_frelocs = 0; | ||
| 1839 | Lisp_Object f_runtime = declare_runtime_imported_funcs (); | ||
| 1824 | FOR_EACH_TAIL (f_runtime) | 1840 | FOR_EACH_TAIL (f_runtime) |
| 1825 | { | 1841 | { |
| 1826 | Lisp_Object el = XCAR (f_runtime); | 1842 | Lisp_Object el = XCAR (f_runtime); |
| 1843 | eassert (n_frelocs < ARRAYELTS (fields)); | ||
| 1827 | fields[n_frelocs++] = xmint_pointer (XCDR (el)); | 1844 | fields[n_frelocs++] = xmint_pointer (XCDR (el)); |
| 1828 | f_reloc_list = Fcons (XCAR (el), f_reloc_list); | ||
| 1829 | } | 1845 | } |
| 1830 | 1846 | ||
| 1831 | FOR_EACH_TAIL (f_subr) | 1847 | Lisp_Object subr_l = Vsubr_list; |
| 1848 | FOR_EACH_TAIL (subr_l) | ||
| 1832 | { | 1849 | { |
| 1833 | Lisp_Object subr_sym = XCAR (f_subr); | 1850 | struct Lisp_Subr *subr = XSUBR (XCAR (subr_l)); |
| 1834 | Lisp_Object subr = symbol_subr (subr_sym); | 1851 | Lisp_Object subr_sym = intern_c_string (subr->symbol_name); |
| 1835 | /* Ignore inliners. This are not real functions to be imported. */ | 1852 | eassert (n_frelocs < ARRAYELTS (fields)); |
| 1836 | if (SUBRP (subr)) | 1853 | fields[n_frelocs++] = declare_imported_func (subr_sym, comp.lisp_obj_type, |
| 1837 | { | 1854 | subr->max_args, NULL); |
| 1838 | Lisp_Object maxarg = XCDR (Fsubr_arity (subr)); | ||
| 1839 | gcc_jit_field *field = | ||
| 1840 | declare_imported_func (subr_sym, comp.lisp_obj_type, | ||
| 1841 | FIXNUMP (maxarg) ? XFIXNUM (maxarg) : | ||
| 1842 | EQ (maxarg, Qmany) ? MANY : UNEVALLED, | ||
| 1843 | NULL); | ||
| 1844 | fields[n_frelocs++] = field; | ||
| 1845 | f_reloc_list = Fcons (subr_sym, f_reloc_list); | ||
| 1846 | } | ||
| 1847 | } | 1855 | } |
| 1848 | 1856 | ||
| 1849 | Lisp_Object f_reloc_vec = make_vector (n_frelocs, Qnil); | ||
| 1850 | f_reloc_list = Fnreverse (f_reloc_list); | ||
| 1851 | ptrdiff_t i = 0; | ||
| 1852 | FOR_EACH_TAIL (f_reloc_list) | ||
| 1853 | { | ||
| 1854 | ASET (f_reloc_vec, i++, XCAR (f_reloc_list)); | ||
| 1855 | } | ||
| 1856 | emit_static_object (TEXT_IMPORTED_FUNC_RELOC_SYM, f_reloc_vec); | ||
| 1857 | |||
| 1858 | gcc_jit_struct *f_reloc_struct = | 1857 | gcc_jit_struct *f_reloc_struct = |
| 1859 | gcc_jit_context_new_struct_type (comp.ctxt, | 1858 | gcc_jit_context_new_struct_type (comp.ctxt, |
| 1860 | NULL, | 1859 | NULL, |
| 1861 | "function_reloc_struct", | 1860 | "freloc_link_table", |
| 1862 | n_frelocs, fields); | 1861 | n_frelocs, fields); |
| 1863 | comp.func_relocs = | 1862 | comp.func_relocs = |
| 1864 | gcc_jit_context_new_global ( | 1863 | gcc_jit_context_new_global ( |
| @@ -1867,8 +1866,6 @@ emit_ctxt_code (void) | |||
| 1867 | GCC_JIT_GLOBAL_EXPORTED, | 1866 | GCC_JIT_GLOBAL_EXPORTED, |
| 1868 | gcc_jit_struct_as_type (f_reloc_struct), | 1867 | gcc_jit_struct_as_type (f_reloc_struct), |
| 1869 | IMPORTED_FUNC_RELOC_SYM); | 1868 | IMPORTED_FUNC_RELOC_SYM); |
| 1870 | |||
| 1871 | SAFE_FREE (); | ||
| 1872 | } | 1869 | } |
| 1873 | 1870 | ||
| 1874 | 1871 | ||
| @@ -3038,8 +3035,8 @@ DEFUN ("comp--init-ctxt", Fcomp__init_ctxt, Scomp__init_ctxt, | |||
| 3038 | 3035 | ||
| 3039 | comp.exported_funcs_h = CALLN (Fmake_hash_table); | 3036 | comp.exported_funcs_h = CALLN (Fmake_hash_table); |
| 3040 | /* | 3037 | /* |
| 3041 | Always reinitialize this cause old function definitions are garbage collected | 3038 | Always reinitialize this cause old function definitions are garbage |
| 3042 | by libgccjit when the ctxt is released. | 3039 | collected by libgccjit when the ctxt is released. |
| 3043 | */ | 3040 | */ |
| 3044 | comp.imported_funcs_h = CALLN (Fmake_hash_table); | 3041 | comp.imported_funcs_h = CALLN (Fmake_hash_table); |
| 3045 | 3042 | ||
| @@ -3140,6 +3137,29 @@ DEFUN ("comp--compile-ctxt-to-file", Fcomp__compile_ctxt_to_file, | |||
| 3140 | } | 3137 | } |
| 3141 | 3138 | ||
| 3142 | 3139 | ||
| 3140 | void | ||
| 3141 | fill_freloc (void) | ||
| 3142 | { | ||
| 3143 | if (ARRAYELTS (helper_link_table) > F_RELOC_MAX_SIZE) | ||
| 3144 | goto overflow; | ||
| 3145 | memcpy (freloc.link_table, helper_link_table, sizeof (freloc.link_table)); | ||
| 3146 | freloc.size = ARRAYELTS (helper_link_table); | ||
| 3147 | |||
| 3148 | Lisp_Object subr_l = Vsubr_list; | ||
| 3149 | FOR_EACH_TAIL (subr_l) | ||
| 3150 | { | ||
| 3151 | if (freloc.size == F_RELOC_MAX_SIZE) | ||
| 3152 | goto overflow; | ||
| 3153 | struct Lisp_Subr *subr = XSUBR (XCAR (subr_l)); | ||
| 3154 | freloc.link_table[freloc.size] = subr->function.a0; | ||
| 3155 | freloc.size++; | ||
| 3156 | } | ||
| 3157 | return; | ||
| 3158 | |||
| 3159 | overflow: | ||
| 3160 | fatal ("Overflowing function relocation table, increase F_RELOC_MAX_SIZE"); | ||
| 3161 | } | ||
| 3162 | |||
| 3143 | /******************************************************************************/ | 3163 | /******************************************************************************/ |
| 3144 | /* Helper functions called from the run-time. */ | 3164 | /* Helper functions called from the run-time. */ |
| 3145 | /* These can't be statics till shared mechanism is used to solve relocations. */ | 3165 | /* These can't be statics till shared mechanism is used to solve relocations. */ |
| @@ -3343,6 +3363,10 @@ DEFUN ("native-elisp-load", Fnative_elisp_load, Snative_elisp_load, 1, 1, 0, | |||
| 3343 | { | 3363 | { |
| 3344 | CHECK_STRING (file); | 3364 | CHECK_STRING (file); |
| 3345 | 3365 | ||
| 3366 | if (!freloc.link_table[0]) | ||
| 3367 | xsignal2 (Qnative_lisp_load_failed, file, | ||
| 3368 | build_string ("Empty relocation table")); | ||
| 3369 | |||
| 3346 | Frequire (Qadvice, Qnil, Qnil); | 3370 | Frequire (Qadvice, Qnil, Qnil); |
| 3347 | 3371 | ||
| 3348 | dynlib_handle_ptr handle = dynlib_open (SSDATA (file)); | 3372 | dynlib_handle_ptr handle = dynlib_open (SSDATA (file)); |
| @@ -3472,6 +3496,10 @@ syms_of_comp (void) | |||
| 3472 | doc: /* The compiler context. */); | 3496 | doc: /* The compiler context. */); |
| 3473 | Vcomp_ctxt = Qnil; | 3497 | Vcomp_ctxt = Qnil; |
| 3474 | 3498 | ||
| 3499 | /* FIXME should be initialized but not here... */ | ||
| 3500 | DEFVAR_LISP ("comp-subr-list", Vsubr_list, | ||
| 3501 | doc: /* List of all defined subrs. */); | ||
| 3502 | |||
| 3475 | /* Load mechanism. */ | 3503 | /* Load mechanism. */ |
| 3476 | staticpro (&Vnative_elisp_refs_hash); | 3504 | staticpro (&Vnative_elisp_refs_hash); |
| 3477 | Vnative_elisp_refs_hash | 3505 | Vnative_elisp_refs_hash |
diff --git a/src/emacs.c b/src/emacs.c index 90ab7ac1e8e..0798e0702f2 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -2050,6 +2050,10 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem | |||
| 2050 | moncontrol (0); | 2050 | moncontrol (0); |
| 2051 | #endif | 2051 | #endif |
| 2052 | 2052 | ||
| 2053 | #ifdef HAVE_NATIVE_COMP | ||
| 2054 | fill_freloc (); | ||
| 2055 | #endif | ||
| 2056 | |||
| 2053 | initialized = true; | 2057 | initialized = true; |
| 2054 | 2058 | ||
| 2055 | if (dump_mode) | 2059 | if (dump_mode) |
diff --git a/src/lisp.h b/src/lisp.h index 25319047a69..d0f7a9720c0 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -4750,9 +4750,10 @@ extern bool profiler_memory_running; | |||
| 4750 | extern void malloc_probe (size_t); | 4750 | extern void malloc_probe (size_t); |
| 4751 | extern void syms_of_profiler (void); | 4751 | extern void syms_of_profiler (void); |
| 4752 | 4752 | ||
| 4753 | /* Defined in comp.c. */ | ||
| 4754 | #ifdef HAVE_NATIVE_COMP | 4753 | #ifdef HAVE_NATIVE_COMP |
| 4754 | /* Defined in comp.c. */ | ||
| 4755 | extern void syms_of_comp (void); | 4755 | extern void syms_of_comp (void); |
| 4756 | extern void fill_freloc (void); | ||
| 4756 | #endif /* HAVE_NATIVE_COMP */ | 4757 | #endif /* HAVE_NATIVE_COMP */ |
| 4757 | 4758 | ||
| 4758 | #ifdef DOS_NT | 4759 | #ifdef DOS_NT |
diff --git a/src/lread.c b/src/lread.c index f280dad97c0..1ba04835aa1 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -4465,6 +4465,9 @@ defsubr (union Aligned_Lisp_Subr *aname) | |||
| 4465 | XSETPVECTYPE (sname, PVEC_SUBR); | 4465 | XSETPVECTYPE (sname, PVEC_SUBR); |
| 4466 | XSETSUBR (tem, sname); | 4466 | XSETSUBR (tem, sname); |
| 4467 | set_symbol_function (sym, tem); | 4467 | set_symbol_function (sym, tem); |
| 4468 | #ifdef HAVE_NATIVE_COMP | ||
| 4469 | Vsubr_list = Fcons (tem, Vsubr_list); | ||
| 4470 | #endif /* HAVE_NATIVE_COMP */ | ||
| 4468 | } | 4471 | } |
| 4469 | 4472 | ||
| 4470 | #ifdef NOTDEF /* Use fset in subr.el now! */ | 4473 | #ifdef NOTDEF /* Use fset in subr.el now! */ |