diff options
| author | Andrea Corallo | 2019-09-02 17:05:15 +0200 |
|---|---|---|
| committer | Andrea Corallo | 2020-01-01 11:37:43 +0100 |
| commit | 6cd45fbf37bd344c87b83424ecaccc8119c30dad (patch) | |
| tree | bba8ffcc71a6b73ecb9ab9ad17cfd6f8098b2318 /src/comp.c | |
| parent | d88d35ffed6c1073a0695ba1e980cb8ea7f09c3a (diff) | |
| download | emacs-6cd45fbf37bd344c87b83424ecaccc8119c30dad.tar.gz emacs-6cd45fbf37bd344c87b83424ecaccc8119c30dad.zip | |
rework stati object serialization
Diffstat (limited to 'src/comp.c')
| -rw-r--r-- | src/comp.c | 183 |
1 files changed, 100 insertions, 83 deletions
diff --git a/src/comp.c b/src/comp.c index 3b2f8e4e74d..d36f239f510 100644 --- a/src/comp.c +++ b/src/comp.c | |||
| @@ -172,6 +172,12 @@ static comp_t comp; | |||
| 172 | 172 | ||
| 173 | FILE *logfile = NULL; | 173 | FILE *logfile = NULL; |
| 174 | 174 | ||
| 175 | /* This is used for serialized objects by the reload mechanism. */ | ||
| 176 | typedef struct { | ||
| 177 | ptrdiff_t len; | ||
| 178 | const char data[]; | ||
| 179 | } static_obj_t; | ||
| 180 | |||
| 175 | 181 | ||
| 176 | /* | 182 | /* |
| 177 | Helper functions called by the runtime. | 183 | Helper functions called by the runtime. |
| @@ -1525,78 +1531,90 @@ emit_integerp (Lisp_Object insn) | |||
| 1525 | &res); | 1531 | &res); |
| 1526 | } | 1532 | } |
| 1527 | 1533 | ||
| 1528 | /* | 1534 | /* This is in charge of serializing an object and export a function to |
| 1529 | Is not possibile to initilize static data in libgccjit therfore will create | 1535 | retrive it at load time. */ |
| 1530 | the following: | ||
| 1531 | |||
| 1532 | char *str_name (void) | ||
| 1533 | { | ||
| 1534 | return "payload here"; | ||
| 1535 | } | ||
| 1536 | */ | ||
| 1537 | |||
| 1538 | static void | 1536 | static void |
| 1539 | emit_literal_string_func (const char *str_name, const char *str) | 1537 | emit_static_object (const char *name, Lisp_Object obj) |
| 1540 | { | 1538 | { |
| 1541 | if (0) /* FIXME: somehow check gcc version here. */ | 1539 | /* libgccjit has no support for initialized static data. |
| 1542 | { | 1540 | The mechanism below is certainly not aesthetic but I assume the bottle neck |
| 1543 | gcc_jit_function *f = | 1541 | in terms of performance at load time will still be the reader. |
| 1544 | gcc_jit_context_new_function (comp.ctxt, NULL, | 1542 | NOTE: we can not relay on it even for valid C strings cause of |
| 1545 | GCC_JIT_FUNCTION_EXPORTED, | 1543 | this funny bug that will affect all pre gcc10 era gccs: |
| 1546 | comp.char_ptr_type, | 1544 | https://gcc.gnu.org/ml/jit/2019-q3/msg00013.html */ |
| 1547 | str_name, | 1545 | |
| 1548 | 0, NULL, 0); | 1546 | Lisp_Object str = Fprin1_to_string (obj, Qnil); |
| 1549 | DECL_BLOCK (block, f); | 1547 | ptrdiff_t len = SBYTES (str); |
| 1550 | gcc_jit_rvalue *res = gcc_jit_context_new_string_literal (comp.ctxt, str); | 1548 | const char *p = SSDATA (str); |
| 1551 | gcc_jit_block_end_with_return (block, NULL, res); | 1549 | |
| 1552 | } else | 1550 | gcc_jit_type *a_type = |
| 1553 | { | 1551 | gcc_jit_context_new_array_type (comp.ctxt, |
| 1554 | /* Horrible workaround for a funny bug: | ||
| 1555 | https://gcc.gnu.org/ml/jit/2019-q3/msg00013.html | ||
| 1556 | This will have to be used for all gccs pre gcc10 era. */ | ||
| 1557 | size_t len = strlen (str); | ||
| 1558 | gcc_jit_type *a_type = | ||
| 1559 | gcc_jit_context_new_array_type (comp.ctxt, | ||
| 1560 | NULL, | ||
| 1561 | comp.char_type, | ||
| 1562 | len + 1); | ||
| 1563 | gcc_jit_function *f = | ||
| 1564 | gcc_jit_context_new_function (comp.ctxt, NULL, | ||
| 1565 | GCC_JIT_FUNCTION_EXPORTED, | ||
| 1566 | gcc_jit_type_get_pointer (a_type), | ||
| 1567 | str_name, | ||
| 1568 | 0, NULL, 0); | ||
| 1569 | DECL_BLOCK (block, f); | ||
| 1570 | gcc_jit_block_add_comment (block, | ||
| 1571 | NULL, | ||
| 1572 | str); | ||
| 1573 | gcc_jit_lvalue *arr = | ||
| 1574 | gcc_jit_context_new_global (comp.ctxt, | ||
| 1575 | NULL, | 1552 | NULL, |
| 1576 | GCC_JIT_GLOBAL_INTERNAL, | 1553 | comp.char_type, |
| 1577 | a_type, | 1554 | len + 1); |
| 1578 | format_string ("arr_%s", str_name)); | 1555 | gcc_jit_field *fields[] = |
| 1579 | for (ptrdiff_t i = 0; i <= len; i++, str++) | 1556 | { gcc_jit_context_new_field (comp.ctxt, |
| 1580 | { | 1557 | NULL, |
| 1581 | char c = i != len ? *str : 0; | 1558 | comp.ptrdiff_type, |
| 1559 | "len"), | ||
| 1560 | gcc_jit_context_new_field (comp.ctxt, | ||
| 1561 | NULL, | ||
| 1562 | a_type, | ||
| 1563 | "data") }; | ||
| 1582 | 1564 | ||
| 1583 | gcc_jit_block_add_assignment ( | 1565 | gcc_jit_type *data_struct_t = |
| 1584 | block, | 1566 | gcc_jit_struct_as_type ( |
| 1585 | NULL, | 1567 | gcc_jit_context_new_struct_type (comp.ctxt, |
| 1586 | gcc_jit_context_new_array_access ( | 1568 | NULL, |
| 1587 | comp.ctxt, | 1569 | format_string ("%s_struct", name), |
| 1588 | NULL, | 1570 | 2, fields)); |
| 1589 | gcc_jit_lvalue_as_rvalue (arr), | 1571 | |
| 1590 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, | 1572 | gcc_jit_lvalue *data_struct = |
| 1591 | comp.ptrdiff_type, | 1573 | gcc_jit_context_new_global (comp.ctxt, |
| 1592 | i)), | 1574 | NULL, |
| 1593 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, | 1575 | GCC_JIT_GLOBAL_INTERNAL, |
| 1594 | comp.char_type, | 1576 | data_struct_t, |
| 1595 | c)); | 1577 | format_string ("%s_s", name)); |
| 1596 | } | 1578 | |
| 1597 | gcc_jit_rvalue *res = gcc_jit_lvalue_get_address (arr, NULL); | 1579 | gcc_jit_function *f = |
| 1598 | gcc_jit_block_end_with_return (block, NULL, res); | 1580 | gcc_jit_context_new_function (comp.ctxt, NULL, |
| 1581 | GCC_JIT_FUNCTION_EXPORTED, | ||
| 1582 | gcc_jit_type_get_pointer (data_struct_t), | ||
| 1583 | name, | ||
| 1584 | 0, NULL, 0); | ||
| 1585 | DECL_BLOCK (block, f); | ||
| 1586 | |||
| 1587 | /* NOTE this truncates if the data has some zero byte before termination. */ | ||
| 1588 | gcc_jit_block_add_comment (block, NULL, p); | ||
| 1589 | |||
| 1590 | gcc_jit_lvalue *arr = | ||
| 1591 | gcc_jit_lvalue_access_field (data_struct, NULL, fields[1]); | ||
| 1592 | |||
| 1593 | for (ptrdiff_t i = 0; i < len; i++, p++) | ||
| 1594 | { | ||
| 1595 | gcc_jit_block_add_assignment ( | ||
| 1596 | block, | ||
| 1597 | NULL, | ||
| 1598 | gcc_jit_context_new_array_access ( | ||
| 1599 | comp.ctxt, | ||
| 1600 | NULL, | ||
| 1601 | gcc_jit_lvalue_as_rvalue (arr), | ||
| 1602 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, | ||
| 1603 | comp.ptrdiff_type, | ||
| 1604 | i)), | ||
| 1605 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, | ||
| 1606 | comp.char_type, | ||
| 1607 | *p)); | ||
| 1599 | } | 1608 | } |
| 1609 | gcc_jit_block_add_assignment ( | ||
| 1610 | block, | ||
| 1611 | NULL, | ||
| 1612 | gcc_jit_lvalue_access_field (data_struct, NULL, fields[0]), | ||
| 1613 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, | ||
| 1614 | comp.ptrdiff_type, | ||
| 1615 | len)); | ||
| 1616 | gcc_jit_rvalue *res = gcc_jit_lvalue_get_address (data_struct, NULL); | ||
| 1617 | gcc_jit_block_end_with_return (block, NULL, res); | ||
| 1600 | } | 1618 | } |
| 1601 | 1619 | ||
| 1602 | /* | 1620 | /* |
| @@ -1667,8 +1685,7 @@ static void | |||
| 1667 | emit_ctxt_code (void) | 1685 | emit_ctxt_code (void) |
| 1668 | { | 1686 | { |
| 1669 | /* Imported objects. */ | 1687 | /* Imported objects. */ |
| 1670 | 1688 | Lisp_Object d_reloc = FUNCALL1 (comp-ctxt-data-relocs, Vcomp_ctxt); | |
| 1671 | const char *d_reloc = SSDATA (FUNCALL1 (comp-ctxt-data-relocs, Vcomp_ctxt)); | ||
| 1672 | EMACS_UINT d_reloc_len = | 1689 | EMACS_UINT d_reloc_len = |
| 1673 | XFIXNUM (FUNCALL1 (hash-table-count, | 1690 | XFIXNUM (FUNCALL1 (hash-table-count, |
| 1674 | FUNCALL1 (comp-ctxt-data-relocs-idx, Vcomp_ctxt))); | 1691 | FUNCALL1 (comp-ctxt-data-relocs-idx, Vcomp_ctxt))); |
| @@ -1685,7 +1702,7 @@ emit_ctxt_code (void) | |||
| 1685 | d_reloc_len), | 1702 | d_reloc_len), |
| 1686 | DATA_RELOC_SYM)); | 1703 | DATA_RELOC_SYM)); |
| 1687 | 1704 | ||
| 1688 | emit_literal_string_func (TEXT_DATA_RELOC_SYM, d_reloc); | 1705 | emit_static_object (TEXT_DATA_RELOC_SYM, d_reloc); |
| 1689 | 1706 | ||
| 1690 | /* Imported functions from non Lisp code. */ | 1707 | /* Imported functions from non Lisp code. */ |
| 1691 | Lisp_Object f_runtime = declare_runtime_imported (); | 1708 | Lisp_Object f_runtime = declare_runtime_imported (); |
| @@ -1729,8 +1746,7 @@ emit_ctxt_code (void) | |||
| 1729 | { | 1746 | { |
| 1730 | ASET (f_reloc_vec, i++, XCAR (f_reloc_list)); | 1747 | ASET (f_reloc_vec, i++, XCAR (f_reloc_list)); |
| 1731 | } | 1748 | } |
| 1732 | emit_literal_string_func (TEXT_IMPORTED_FUNC_RELOC_SYM, | 1749 | emit_static_object (TEXT_IMPORTED_FUNC_RELOC_SYM, f_reloc_vec); |
| 1733 | (SSDATA (Fprin1_to_string (f_reloc_vec, Qnil)))); | ||
| 1734 | 1750 | ||
| 1735 | gcc_jit_struct *f_reloc_struct = | 1751 | gcc_jit_struct *f_reloc_struct = |
| 1736 | gcc_jit_context_new_struct_type (comp.ctxt, | 1752 | gcc_jit_context_new_struct_type (comp.ctxt, |
| @@ -1746,8 +1762,8 @@ emit_ctxt_code (void) | |||
| 1746 | IMPORTED_FUNC_RELOC_SYM); | 1762 | IMPORTED_FUNC_RELOC_SYM); |
| 1747 | 1763 | ||
| 1748 | /* Exported functions info. */ | 1764 | /* Exported functions info. */ |
| 1749 | const char *func_list = SSDATA (FUNCALL1 (comp-ctxt-funcs, Vcomp_ctxt)); | 1765 | Lisp_Object func_list = FUNCALL1 (comp-ctxt-funcs, Vcomp_ctxt); |
| 1750 | emit_literal_string_func (TEXT_EXPORTED_FUNC_RELOC_SYM, func_list); | 1766 | emit_static_object (TEXT_EXPORTED_FUNC_RELOC_SYM, func_list); |
| 1751 | } | 1767 | } |
| 1752 | 1768 | ||
| 1753 | 1769 | ||
| @@ -3060,21 +3076,22 @@ helper_set_data_relocs (Lisp_Object *d_relocs_vec, char const *relocs) | |||
| 3060 | 3076 | ||
| 3061 | static Lisp_Object Vnative_elisp_refs_hash; | 3077 | static Lisp_Object Vnative_elisp_refs_hash; |
| 3062 | 3078 | ||
| 3063 | typedef char *(*comp_litt_str_func) (void); | ||
| 3064 | |||
| 3065 | static void | 3079 | static void |
| 3066 | prevent_gc (Lisp_Object obj) | 3080 | prevent_gc (Lisp_Object obj) |
| 3067 | { | 3081 | { |
| 3068 | Fputhash (obj, Qt, Vnative_elisp_refs_hash); | 3082 | Fputhash (obj, Qt, Vnative_elisp_refs_hash); |
| 3069 | } | 3083 | } |
| 3070 | 3084 | ||
| 3085 | typedef char *(*comp_lit_str_func) (void); | ||
| 3086 | |||
| 3087 | /* Deserialize read and return static object. */ | ||
| 3071 | static Lisp_Object | 3088 | static Lisp_Object |
| 3072 | retrive_literal_obj (dynlib_handle_ptr handle, const char *str_name) | 3089 | load_static_obj (dynlib_handle_ptr handle, const char *name) |
| 3073 | { | 3090 | { |
| 3074 | comp_litt_str_func f = dynlib_sym (handle, str_name); | 3091 | static_obj_t *(*f)(void) = dynlib_sym (handle, name); |
| 3075 | eassert (f); | 3092 | eassert (f); |
| 3076 | char *res = f(); | 3093 | static_obj_t *res = f(); |
| 3077 | return Fread (build_string (res)); | 3094 | return Fread (make_string (res->data, res->len)); |
| 3078 | } | 3095 | } |
| 3079 | 3096 | ||
| 3080 | static int | 3097 | static int |
| @@ -3083,7 +3100,7 @@ load_comp_unit (dynlib_handle_ptr handle) | |||
| 3083 | /* Imported data. */ | 3100 | /* Imported data. */ |
| 3084 | Lisp_Object *data_relocs = dynlib_sym (handle, DATA_RELOC_SYM); | 3101 | Lisp_Object *data_relocs = dynlib_sym (handle, DATA_RELOC_SYM); |
| 3085 | 3102 | ||
| 3086 | Lisp_Object d_vec = retrive_literal_obj (handle, TEXT_DATA_RELOC_SYM); | 3103 | Lisp_Object d_vec = load_static_obj (handle, TEXT_DATA_RELOC_SYM); |
| 3087 | EMACS_UINT d_vec_len = XFIXNUM (Flength (d_vec)); | 3104 | EMACS_UINT d_vec_len = XFIXNUM (Flength (d_vec)); |
| 3088 | 3105 | ||
| 3089 | for (EMACS_UINT i = 0; i < d_vec_len; i++) | 3106 | for (EMACS_UINT i = 0; i < d_vec_len; i++) |
| @@ -3096,7 +3113,7 @@ load_comp_unit (dynlib_handle_ptr handle) | |||
| 3096 | Lisp_Object (**f_relocs)(void) = | 3113 | Lisp_Object (**f_relocs)(void) = |
| 3097 | dynlib_sym (handle, IMPORTED_FUNC_RELOC_SYM); | 3114 | dynlib_sym (handle, IMPORTED_FUNC_RELOC_SYM); |
| 3098 | Lisp_Object f_vec = | 3115 | Lisp_Object f_vec = |
| 3099 | retrive_literal_obj (handle, TEXT_IMPORTED_FUNC_RELOC_SYM); | 3116 | load_static_obj (handle, TEXT_IMPORTED_FUNC_RELOC_SYM); |
| 3100 | EMACS_UINT f_vec_len = XFIXNUM (Flength (f_vec)); | 3117 | EMACS_UINT f_vec_len = XFIXNUM (Flength (f_vec)); |
| 3101 | for (EMACS_UINT i = 0; i < f_vec_len; i++) | 3118 | for (EMACS_UINT i = 0; i < f_vec_len; i++) |
| 3102 | { | 3119 | { |
| @@ -3144,7 +3161,7 @@ load_comp_unit (dynlib_handle_ptr handle) | |||
| 3144 | } | 3161 | } |
| 3145 | 3162 | ||
| 3146 | /* Exported functions. */ | 3163 | /* Exported functions. */ |
| 3147 | Lisp_Object func_list = retrive_literal_obj (handle, TEXT_EXPORTED_FUNC_RELOC_SYM); | 3164 | Lisp_Object func_list = load_static_obj (handle, TEXT_EXPORTED_FUNC_RELOC_SYM); |
| 3148 | 3165 | ||
| 3149 | while (func_list) | 3166 | while (func_list) |
| 3150 | { | 3167 | { |