aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrea Corallo2020-01-12 11:47:50 +0100
committerAndrea Corallo2020-01-12 13:22:30 +0100
commitc1d034fc27e3aef2370cf0153e7b54dac7eba91b (patch)
treee2d2b7ecd53c50751a3ff0818dc0788d9f328eab
parent93ed2c32dfd2e385ab0b75e9cbc0768c29b15b50 (diff)
downloademacs-c1d034fc27e3aef2370cf0153e7b54dac7eba91b.tar.gz
emacs-c1d034fc27e3aef2370cf0153e7b54dac7eba91b.zip
Split relocated data into two separate arrays
Rework the functionality of the previous commit to be more efficient.
-rw-r--r--lisp/emacs-lisp/comp.el44
-rw-r--r--src/comp.c108
-rw-r--r--src/comp.h3
-rw-r--r--src/lisp.h4
4 files changed, 106 insertions, 53 deletions
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index 0f71746407a..69141f657a6 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -157,6 +157,13 @@ Can be used by code that wants to expand differently in this case.")
157 finally return h) 157 finally return h)
158 "Hash table lap-op -> stack adjustment.")) 158 "Hash table lap-op -> stack adjustment."))
159 159
160(cl-defstruct comp-data-container
161 "Data relocation container structure."
162 (l () :type list
163 :documentation "Constant objects used by functions.")
164 (idx (make-hash-table :test #'equal) :type hash-table
165 :documentation "Obj -> position into the previous field."))
166
160(cl-defstruct comp-ctxt 167(cl-defstruct comp-ctxt
161 "Lisp side of the compiler context." 168 "Lisp side of the compiler context."
162 (output nil :type string 169 (output nil :type string
@@ -166,10 +173,11 @@ Can be used by code that wants to expand differently in this case.")
166 (funcs-h (make-hash-table) :type hash-table 173 (funcs-h (make-hash-table) :type hash-table
167 :documentation "lisp-func-name -> comp-func. 174 :documentation "lisp-func-name -> comp-func.
168This is to build the prev field.") 175This is to build the prev field.")
169 (data-relocs-l () :type list 176 (d-base (make-comp-data-container) :type comp-data-container
170 :documentation "List of pairs (impure . obj-to-reloc).") 177 :documentation "Standard data relocated in use by functions.")
171 (data-relocs-idx (make-hash-table :test #'equal) :type hash-table 178 (d-impure (make-comp-data-container) :type comp-data-container
172 :documentation "Obj -> position into data-relocs.")) 179 :documentation "Data relocated that cannot be moved into pure space.
180This is tipically for top-level forms other than defun."))
173 181
174(cl-defstruct comp-args-base 182(cl-defstruct comp-args-base
175 (min nil :type number 183 (min nil :type number
@@ -314,16 +322,28 @@ structure.")
314 "Type hint predicate for function name FUNC." 322 "Type hint predicate for function name FUNC."
315 (when (member func comp-type-hints) t)) 323 (when (member func comp-type-hints) t))
316 324
325(defun comp-data-container-check (cont)
326 "Sanity check CONT coherency."
327 (cl-assert (= (length (comp-data-container-l cont))
328 (hash-table-count (comp-data-container-idx cont)))))
329
330(defun comp-add-const-to-relocs-to-cont (obj cont)
331 "Keep track of OBJ into the CONT relocation container.
332The corresponding index is returned."
333 (let ((h (comp-data-container-idx cont)))
334 (if-let ((idx (gethash obj h)))
335 idx
336 (push obj (comp-data-container-l cont))
337 (puthash obj (hash-table-count h) h))))
338
317(defun comp-add-const-to-relocs (obj &optional impure) 339(defun comp-add-const-to-relocs (obj &optional impure)
318 "Keep track of OBJ into the ctxt relocations. 340 "Keep track of OBJ into the ctxt relocations.
319When IMPURE is non nil OBJ cannot be copied into pure space. 341When IMPURE is non nil OBJ cannot be copied into pure space.
320The corresponding index is returned." 342The corresponding index is returned."
321 (let ((data-relocs-idx (comp-ctxt-data-relocs-idx comp-ctxt)) 343 (comp-add-const-to-relocs-to-cont obj
322 (packed-obj (cons impure obj))) 344 (if impure
323 (if-let ((idx (gethash packed-obj data-relocs-idx))) 345 (comp-ctxt-d-impure comp-ctxt)
324 idx 346 (comp-ctxt-d-base comp-ctxt))))
325 (push packed-obj (comp-ctxt-data-relocs-l comp-ctxt))
326 (puthash packed-obj (hash-table-count data-relocs-idx) data-relocs-idx))))
327 347
328(defmacro comp-within-log-buff (&rest body) 348(defmacro comp-within-log-buff (&rest body)
329 "Execute BODY while at the end the log-buffer. 349 "Execute BODY while at the end the log-buffer.
@@ -1810,8 +1830,8 @@ These are substituted with a normal 'set' op."
1810(defun comp-compile-ctxt-to-file (name) 1830(defun comp-compile-ctxt-to-file (name)
1811 "Compile as native code the current context naming it NAME. 1831 "Compile as native code the current context naming it NAME.
1812Prepare every function for final compilation and drive the C back-end." 1832Prepare every function for final compilation and drive the C back-end."
1813 (cl-assert (= (length (comp-ctxt-data-relocs-l comp-ctxt)) 1833 (comp-data-container-check (comp-ctxt-d-base comp-ctxt))
1814 (hash-table-count (comp-ctxt-data-relocs-idx comp-ctxt)))) 1834 (comp-data-container-check (comp-ctxt-d-impure comp-ctxt))
1815 (comp--compile-ctxt-to-file name)) 1835 (comp--compile-ctxt-to-file name))
1816 1836
1817(defun comp-final (_) 1837(defun comp-final (_)
diff --git a/src/comp.c b/src/comp.c
index 0d1f83eb8ff..290fc3a9c45 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -39,9 +39,11 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
39#define CURRENT_THREAD_RELOC_SYM "current_thread_reloc" 39#define CURRENT_THREAD_RELOC_SYM "current_thread_reloc"
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 FUNC_LINK_TABLE_SYM "freloc_link_table" 43#define FUNC_LINK_TABLE_SYM "freloc_link_table"
43#define LINK_TABLE_HASH_SYM "freloc_hash" 44#define LINK_TABLE_HASH_SYM "freloc_hash"
44#define TEXT_DATA_RELOC_SYM "text_data_reloc" 45#define TEXT_DATA_RELOC_SYM "text_data_reloc"
46#define TEXT_DATA_RELOC_IMPURE_SYM "text_data_reloc_imp"
45 47
46#define SPEED XFIXNUM (Fsymbol_value (Qcomp_speed)) 48#define SPEED XFIXNUM (Fsymbol_value (Qcomp_speed))
47#define COMP_DEBUG XFIXNUM (Fsymbol_value (Qcomp_debug)) 49#define COMP_DEBUG XFIXNUM (Fsymbol_value (Qcomp_debug))
@@ -171,8 +173,12 @@ typedef struct {
171 Lisp_Object exported_funcs_h; /* subr_name -> gcc_jit_function *. */ 173 Lisp_Object exported_funcs_h; /* subr_name -> gcc_jit_function *. */
172 Lisp_Object imported_funcs_h; /* subr_name -> gcc_jit_field *reloc_field. */ 174 Lisp_Object imported_funcs_h; /* subr_name -> gcc_jit_field *reloc_field. */
173 Lisp_Object emitter_dispatcher; 175 Lisp_Object emitter_dispatcher;
174 gcc_jit_rvalue *data_relocs; /* Synthesized struct holding data relocs. */ 176 /* Synthesized struct holding data relocs. */
175 gcc_jit_lvalue *func_relocs; /* Synthesized struct holding func relocs. */ 177 gcc_jit_rvalue *data_relocs;
178 /* Same as before but can't go in pure space. */
179 gcc_jit_rvalue *data_relocs_impure;
180 /* Synthesized struct holding func relocs. */
181 gcc_jit_lvalue *func_relocs;
176} comp_t; 182} comp_t;
177 183
178static comp_t comp; 184static comp_t comp;
@@ -894,9 +900,10 @@ emit_const_lisp_obj (Lisp_Object obj, Lisp_Object impure)
894 comp.void_ptr_type, 900 comp.void_ptr_type,
895 NULL)); 901 NULL));
896 902
897 Lisp_Object d_reloc_idx = CALL1I (comp-ctxt-data-relocs-idx, Vcomp_ctxt); 903 Lisp_Object container = impure ? CALL1I (comp-ctxt-d-impure, Vcomp_ctxt)
898 Lisp_Object packed_obj = Fcons (impure, obj); 904 : CALL1I (comp-ctxt-d-base, Vcomp_ctxt);
899 Lisp_Object reloc_idx = Fgethash (packed_obj, d_reloc_idx, Qnil); 905 Lisp_Object reloc_idx =
906 Fgethash (obj, CALL1I (comp-data-container-idx, container), Qnil);
900 eassert (!NILP (reloc_idx)); 907 eassert (!NILP (reloc_idx));
901 gcc_jit_rvalue *reloc_n = 908 gcc_jit_rvalue *reloc_n =
902 gcc_jit_context_new_rvalue_from_int (comp.ctxt, 909 gcc_jit_context_new_rvalue_from_int (comp.ctxt,
@@ -906,7 +913,8 @@ emit_const_lisp_obj (Lisp_Object obj, Lisp_Object impure)
906 gcc_jit_lvalue_as_rvalue ( 913 gcc_jit_lvalue_as_rvalue (
907 gcc_jit_context_new_array_access (comp.ctxt, 914 gcc_jit_context_new_array_access (comp.ctxt,
908 NULL, 915 NULL,
909 comp.data_relocs, 916 impure ? comp.data_relocs_impure
917 : comp.data_relocs,
910 reloc_n)); 918 reloc_n));
911} 919}
912 920
@@ -1749,14 +1757,52 @@ emit_static_object (const char *name, Lisp_Object obj)
1749 gcc_jit_block_end_with_return (block, NULL, res); 1757 gcc_jit_block_end_with_return (block, NULL, res);
1750} 1758}
1751 1759
1760static gcc_jit_rvalue *
1761declare_imported_data_relocs (Lisp_Object container, const char *code_symbol,
1762 const char *text_symbol)
1763{
1764 /* Imported objects. */
1765 EMACS_INT d_reloc_len =
1766 XFIXNUM (CALL1I (hash-table-count,
1767 CALL1I (comp-data-container-idx, container)));
1768 Lisp_Object d_reloc = Fnreverse (CALL1I (comp-data-container-l, container));
1769 d_reloc = Fvconcat (1, &d_reloc);
1770
1771 gcc_jit_rvalue *reloc_struct =
1772 gcc_jit_lvalue_as_rvalue (
1773 gcc_jit_context_new_global (
1774 comp.ctxt,
1775 NULL,
1776 GCC_JIT_GLOBAL_EXPORTED,
1777 gcc_jit_context_new_array_type (comp.ctxt,
1778 NULL,
1779 comp.lisp_obj_type,
1780 d_reloc_len),
1781 code_symbol));
1782
1783 emit_static_object (text_symbol, d_reloc);
1784
1785 return reloc_struct;
1786}
1787
1752static void 1788static void
1753declare_runtime_imported_data (void) 1789declare_imported_data (void)
1754{ 1790{
1755 /* Imported symbols by inliner functions. */ 1791 /* Imported symbols by inliner functions. */
1756 CALL1I (comp-add-const-to-relocs, Qnil); 1792 CALL1I (comp-add-const-to-relocs, Qnil);
1757 CALL1I (comp-add-const-to-relocs, Qt); 1793 CALL1I (comp-add-const-to-relocs, Qt);
1758 CALL1I (comp-add-const-to-relocs, Qconsp); 1794 CALL1I (comp-add-const-to-relocs, Qconsp);
1759 CALL1I (comp-add-const-to-relocs, Qlistp); 1795 CALL1I (comp-add-const-to-relocs, Qlistp);
1796
1797 /* Imported objects. */
1798 comp.data_relocs =
1799 declare_imported_data_relocs (CALL1I (comp-ctxt-d-base, Vcomp_ctxt),
1800 DATA_RELOC_SYM,
1801 TEXT_DATA_RELOC_SYM);
1802 comp.data_relocs_impure =
1803 declare_imported_data_relocs (CALL1I (comp-ctxt-d-impure, Vcomp_ctxt),
1804 DATA_RELOC_IMPURE_SYM,
1805 TEXT_DATA_RELOC_IMPURE_SYM);
1760} 1806}
1761 1807
1762/* 1808/*
@@ -1842,27 +1888,7 @@ emit_ctxt_code (void)
1842 gcc_jit_type_get_pointer (comp.void_ptr_type), 1888 gcc_jit_type_get_pointer (comp.void_ptr_type),
1843 PURE_RELOC_SYM)); 1889 PURE_RELOC_SYM));
1844 1890
1845 declare_runtime_imported_data (); 1891 declare_imported_data ();
1846 /* Imported objects. */
1847 EMACS_INT d_reloc_len =
1848 XFIXNUM (CALL1I (hash-table-count,
1849 CALL1I (comp-ctxt-data-relocs-idx, Vcomp_ctxt)));
1850 Lisp_Object d_reloc = Fnreverse (CALL1I (comp-ctxt-data-relocs-l, Vcomp_ctxt));
1851 d_reloc = Fvconcat (1, &d_reloc);
1852
1853 comp.data_relocs =
1854 gcc_jit_lvalue_as_rvalue (
1855 gcc_jit_context_new_global (
1856 comp.ctxt,
1857 NULL,
1858 GCC_JIT_GLOBAL_EXPORTED,
1859 gcc_jit_context_new_array_type (comp.ctxt,
1860 NULL,
1861 comp.lisp_obj_type,
1862 d_reloc_len),
1863 DATA_RELOC_SYM));
1864
1865 emit_static_object (TEXT_DATA_RELOC_SYM, d_reloc);
1866 1892
1867 /* Functions imported from Lisp code. */ 1893 /* Functions imported from Lisp code. */
1868 freloc_check_fill (); 1894 freloc_check_fill ();
@@ -3263,12 +3289,14 @@ load_comp_unit (struct Lisp_Native_Comp_Unit *comp_u, bool loading_dump)
3263 dynlib_sym (handle, CURRENT_THREAD_RELOC_SYM); 3289 dynlib_sym (handle, CURRENT_THREAD_RELOC_SYM);
3264 EMACS_INT ***pure_reloc = dynlib_sym (handle, PURE_RELOC_SYM); 3290 EMACS_INT ***pure_reloc = dynlib_sym (handle, PURE_RELOC_SYM);
3265 Lisp_Object *data_relocs = dynlib_sym (handle, DATA_RELOC_SYM); 3291 Lisp_Object *data_relocs = dynlib_sym (handle, DATA_RELOC_SYM);
3292 Lisp_Object *data_imp_relocs = dynlib_sym (handle, DATA_RELOC_IMPURE_SYM);
3266 void **freloc_link_table = dynlib_sym (handle, FUNC_LINK_TABLE_SYM); 3293 void **freloc_link_table = dynlib_sym (handle, FUNC_LINK_TABLE_SYM);
3267 void (*top_level_run)(Lisp_Object) = dynlib_sym (handle, "top_level_run"); 3294 void (*top_level_run)(Lisp_Object) = dynlib_sym (handle, "top_level_run");
3268 3295
3269 if (!(current_thread_reloc 3296 if (!(current_thread_reloc
3270 && pure_reloc 3297 && pure_reloc
3271 && data_relocs 3298 && data_relocs
3299 && data_imp_relocs
3272 && freloc_link_table 3300 && freloc_link_table
3273 && top_level_run) 3301 && top_level_run)
3274 || NILP (Fstring_equal (load_static_obj (comp_u, LINK_TABLE_HASH_SYM), 3302 || NILP (Fstring_equal (load_static_obj (comp_u, LINK_TABLE_HASH_SYM),
@@ -3283,21 +3311,23 @@ load_comp_unit (struct Lisp_Native_Comp_Unit *comp_u, bool loading_dump)
3283 3311
3284 /* Imported data. */ 3312 /* Imported data. */
3285 if (!loading_dump) 3313 if (!loading_dump)
3286 comp_u->data_vec = load_static_obj (comp_u, TEXT_DATA_RELOC_SYM); 3314 {
3315 comp_u->data_vec = load_static_obj (comp_u, TEXT_DATA_RELOC_SYM);
3316 comp_u->data_impure_vec =
3317 load_static_obj (comp_u, TEXT_DATA_RELOC_IMPURE_SYM);
3287 3318
3288 EMACS_INT d_vec_len = XFIXNUM (Flength (comp_u->data_vec)); 3319 if (!NILP (Vpurify_flag))
3320 /* Non impure can be copied into pure space. */
3321 comp_u->data_vec = Fpurecopy (comp_u->data_vec);
3322 }
3289 3323
3290 if (!loading_dump && !NILP (Vpurify_flag)) 3324 EMACS_INT d_vec_len = XFIXNUM (Flength (comp_u->data_vec));
3291 for (EMACS_INT i = 0; i < d_vec_len; i++) 3325 for (EMACS_INT i = 0; i < d_vec_len; i++)
3292 { 3326 data_relocs[i] = AREF (comp_u->data_vec, i);
3293 Lisp_Object packed_obj = AREF (comp_u->data_vec, i);
3294 if (NILP (XCAR (packed_obj)))
3295 /* If is not impure can be copied into pure space. */
3296 XSETCDR (packed_obj, Fpurecopy (XCDR (packed_obj)));
3297 }
3298 3327
3328 d_vec_len = XFIXNUM (Flength (comp_u->data_impure_vec));
3299 for (EMACS_INT i = 0; i < d_vec_len; i++) 3329 for (EMACS_INT i = 0; i < d_vec_len; i++)
3300 data_relocs[i] = XCDR (AREF (comp_u->data_vec, i)); 3330 data_imp_relocs[i] = AREF (comp_u->data_impure_vec, i);
3301 3331
3302 if (!loading_dump) 3332 if (!loading_dump)
3303 { 3333 {
diff --git a/src/comp.h b/src/comp.h
index 86fa54f5158..ddebbbcccf0 100644
--- a/src/comp.h
+++ b/src/comp.h
@@ -38,6 +38,9 @@ struct Lisp_Native_Comp_Unit
38 Lisp_Object file; 38 Lisp_Object file;
39 /* Analogous to the constant vector but per compilation unit. */ 39 /* Analogous to the constant vector but per compilation unit. */
40 Lisp_Object data_vec; 40 Lisp_Object data_vec;
41 /* Same but for data that cannot be moved to pure space.
42 Must be the last lisp object here. */
43 Lisp_Object data_impure_vec;
41 dynlib_handle_ptr handle; 44 dynlib_handle_ptr handle;
42}; 45};
43 46
diff --git a/src/lisp.h b/src/lisp.h
index 2d083dc4582..04489959ed8 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4767,8 +4767,8 @@ SUBR_NATIVE_COMPILEDP (Lisp_Object a)
4767INLINE struct Lisp_Native_Comp_Unit * 4767INLINE struct Lisp_Native_Comp_Unit *
4768allocate_native_comp_unit (void) 4768allocate_native_comp_unit (void)
4769{ 4769{
4770 return ALLOCATE_ZEROED_PSEUDOVECTOR (struct Lisp_Native_Comp_Unit, data_vec, 4770 return ALLOCATE_ZEROED_PSEUDOVECTOR (struct Lisp_Native_Comp_Unit,
4771 PVEC_NATIVE_COMP_UNIT); 4771 data_impure_vec, PVEC_NATIVE_COMP_UNIT);
4772} 4772}
4773#else 4773#else
4774INLINE bool 4774INLINE bool