diff options
| author | Andrea Corallo | 2020-01-12 11:47:50 +0100 |
|---|---|---|
| committer | Andrea Corallo | 2020-01-12 13:22:30 +0100 |
| commit | c1d034fc27e3aef2370cf0153e7b54dac7eba91b (patch) | |
| tree | e2d2b7ecd53c50751a3ff0818dc0788d9f328eab | |
| parent | 93ed2c32dfd2e385ab0b75e9cbc0768c29b15b50 (diff) | |
| download | emacs-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.el | 44 | ||||
| -rw-r--r-- | src/comp.c | 108 | ||||
| -rw-r--r-- | src/comp.h | 3 | ||||
| -rw-r--r-- | src/lisp.h | 4 |
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. |
| 168 | This is to build the prev field.") | 175 | This 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. |
| 180 | This 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. | ||
| 332 | The 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. |
| 319 | When IMPURE is non nil OBJ cannot be copied into pure space. | 341 | When IMPURE is non nil OBJ cannot be copied into pure space. |
| 320 | The corresponding index is returned." | 342 | The 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. |
| 1812 | Prepare every function for final compilation and drive the C back-end." | 1832 | Prepare 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 | ||
| 178 | static comp_t comp; | 184 | static 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 | ||
| 1760 | static gcc_jit_rvalue * | ||
| 1761 | declare_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 | |||
| 1752 | static void | 1788 | static void |
| 1753 | declare_runtime_imported_data (void) | 1789 | declare_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) | |||
| 4767 | INLINE struct Lisp_Native_Comp_Unit * | 4767 | INLINE struct Lisp_Native_Comp_Unit * |
| 4768 | allocate_native_comp_unit (void) | 4768 | allocate_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 |
| 4774 | INLINE bool | 4774 | INLINE bool |