aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrea Corallo2019-12-14 09:28:12 +0100
committerAndrea Corallo2020-01-01 11:38:13 +0100
commit694ece772220346aef12520bc66ca401d08809bb (patch)
tree01a29820fbb8ab0e2567f47b48b39f010107283b /src
parent740462da6153b111a8196b003791a55c7f7fa878 (diff)
downloademacs-694ece772220346aef12520bc66ca401d08809bb.tar.gz
emacs-694ece772220346aef12520bc66ca401d08809bb.zip
reworking relocation mechanism to use one single table
Diffstat (limited to 'src')
-rw-r--r--src/comp.c116
-rw-r--r--src/emacs.c4
-rw-r--r--src/lisp.h3
-rw-r--r--src/lread.c3
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
76typedef struct {
77 void *link_table[F_RELOC_MAX_SIZE];
78 ptrdiff_t size;
79} f_reloc_t;
80
81static f_reloc_t freloc;
82
73/* C side of the compiler context. */ 83/* C side of the compiler context. */
74 84
75typedef struct { 85typedef 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);
184void helper_save_restriction (void); 194void helper_save_restriction (void);
185bool helper_PSEUDOVECTOR_TYPEP_XUNTAG (Lisp_Object a, enum pvec_type code); 195bool helper_PSEUDOVECTOR_TYPEP_XUNTAG (Lisp_Object a, enum pvec_type code);
186 196
197void *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
188static char * ATTRIBUTE_FORMAT_PRINTF (1, 2) 212static char * ATTRIBUTE_FORMAT_PRINTF (1, 2)
189format_string (const char *format, ...) 213format_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)
1767static void 1791static void
1768emit_ctxt_code (void) 1792emit_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
3140void
3141fill_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;
4750extern void malloc_probe (size_t); 4750extern void malloc_probe (size_t);
4751extern void syms_of_profiler (void); 4751extern 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. */
4755extern void syms_of_comp (void); 4755extern void syms_of_comp (void);
4756extern 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! */