aboutsummaryrefslogtreecommitdiffstats
path: root/src/comp.c
diff options
context:
space:
mode:
authorAndrea Corallo2019-09-02 17:05:15 +0200
committerAndrea Corallo2020-01-01 11:37:43 +0100
commit6cd45fbf37bd344c87b83424ecaccc8119c30dad (patch)
treebba8ffcc71a6b73ecb9ab9ad17cfd6f8098b2318 /src/comp.c
parentd88d35ffed6c1073a0695ba1e980cb8ea7f09c3a (diff)
downloademacs-6cd45fbf37bd344c87b83424ecaccc8119c30dad.tar.gz
emacs-6cd45fbf37bd344c87b83424ecaccc8119c30dad.zip
rework stati object serialization
Diffstat (limited to 'src/comp.c')
-rw-r--r--src/comp.c183
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
173FILE *logfile = NULL; 173FILE *logfile = NULL;
174 174
175/* This is used for serialized objects by the reload mechanism. */
176typedef 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
1538static void 1536static void
1539emit_literal_string_func (const char *str_name, const char *str) 1537emit_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
1667emit_ctxt_code (void) 1685emit_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
3061static Lisp_Object Vnative_elisp_refs_hash; 3077static Lisp_Object Vnative_elisp_refs_hash;
3062 3078
3063typedef char *(*comp_litt_str_func) (void);
3064
3065static void 3079static void
3066prevent_gc (Lisp_Object obj) 3080prevent_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
3085typedef char *(*comp_lit_str_func) (void);
3086
3087/* Deserialize read and return static object. */
3071static Lisp_Object 3088static Lisp_Object
3072retrive_literal_obj (dynlib_handle_ptr handle, const char *str_name) 3089load_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
3080static int 3097static 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 {