mirror of
https://github.com/masscollaborationlabs/emacs.git
synced 2025-07-19 02:10:10 +00:00
Split relocated data into two separate arrays
Rework the functionality of the previous commit to be more efficient.
This commit is contained in:
parent
93ed2c32df
commit
c1d034fc27
4 changed files with 107 additions and 54 deletions
|
@ -157,6 +157,13 @@ Can be used by code that wants to expand differently in this case.")
|
||||||
finally return h)
|
finally return h)
|
||||||
"Hash table lap-op -> stack adjustment."))
|
"Hash table lap-op -> stack adjustment."))
|
||||||
|
|
||||||
|
(cl-defstruct comp-data-container
|
||||||
|
"Data relocation container structure."
|
||||||
|
(l () :type list
|
||||||
|
:documentation "Constant objects used by functions.")
|
||||||
|
(idx (make-hash-table :test #'equal) :type hash-table
|
||||||
|
:documentation "Obj -> position into the previous field."))
|
||||||
|
|
||||||
(cl-defstruct comp-ctxt
|
(cl-defstruct comp-ctxt
|
||||||
"Lisp side of the compiler context."
|
"Lisp side of the compiler context."
|
||||||
(output nil :type string
|
(output nil :type string
|
||||||
|
@ -166,10 +173,11 @@ Can be used by code that wants to expand differently in this case.")
|
||||||
(funcs-h (make-hash-table) :type hash-table
|
(funcs-h (make-hash-table) :type hash-table
|
||||||
:documentation "lisp-func-name -> comp-func.
|
:documentation "lisp-func-name -> comp-func.
|
||||||
This is to build the prev field.")
|
This is to build the prev field.")
|
||||||
(data-relocs-l () :type list
|
(d-base (make-comp-data-container) :type comp-data-container
|
||||||
:documentation "List of pairs (impure . obj-to-reloc).")
|
:documentation "Standard data relocated in use by functions.")
|
||||||
(data-relocs-idx (make-hash-table :test #'equal) :type hash-table
|
(d-impure (make-comp-data-container) :type comp-data-container
|
||||||
:documentation "Obj -> position into data-relocs."))
|
:documentation "Data relocated that cannot be moved into pure space.
|
||||||
|
This is tipically for top-level forms other than defun."))
|
||||||
|
|
||||||
(cl-defstruct comp-args-base
|
(cl-defstruct comp-args-base
|
||||||
(min nil :type number
|
(min nil :type number
|
||||||
|
@ -314,16 +322,28 @@ structure.")
|
||||||
"Type hint predicate for function name FUNC."
|
"Type hint predicate for function name FUNC."
|
||||||
(when (member func comp-type-hints) t))
|
(when (member func comp-type-hints) t))
|
||||||
|
|
||||||
|
(defun comp-data-container-check (cont)
|
||||||
|
"Sanity check CONT coherency."
|
||||||
|
(cl-assert (= (length (comp-data-container-l cont))
|
||||||
|
(hash-table-count (comp-data-container-idx cont)))))
|
||||||
|
|
||||||
|
(defun comp-add-const-to-relocs-to-cont (obj cont)
|
||||||
|
"Keep track of OBJ into the CONT relocation container.
|
||||||
|
The corresponding index is returned."
|
||||||
|
(let ((h (comp-data-container-idx cont)))
|
||||||
|
(if-let ((idx (gethash obj h)))
|
||||||
|
idx
|
||||||
|
(push obj (comp-data-container-l cont))
|
||||||
|
(puthash obj (hash-table-count h) h))))
|
||||||
|
|
||||||
(defun comp-add-const-to-relocs (obj &optional impure)
|
(defun comp-add-const-to-relocs (obj &optional impure)
|
||||||
"Keep track of OBJ into the ctxt relocations.
|
"Keep track of OBJ into the ctxt relocations.
|
||||||
When IMPURE is non nil OBJ cannot be copied into pure space.
|
When IMPURE is non nil OBJ cannot be copied into pure space.
|
||||||
The corresponding index is returned."
|
The corresponding index is returned."
|
||||||
(let ((data-relocs-idx (comp-ctxt-data-relocs-idx comp-ctxt))
|
(comp-add-const-to-relocs-to-cont obj
|
||||||
(packed-obj (cons impure obj)))
|
(if impure
|
||||||
(if-let ((idx (gethash packed-obj data-relocs-idx)))
|
(comp-ctxt-d-impure comp-ctxt)
|
||||||
idx
|
(comp-ctxt-d-base comp-ctxt))))
|
||||||
(push packed-obj (comp-ctxt-data-relocs-l comp-ctxt))
|
|
||||||
(puthash packed-obj (hash-table-count data-relocs-idx) data-relocs-idx))))
|
|
||||||
|
|
||||||
(defmacro comp-within-log-buff (&rest body)
|
(defmacro comp-within-log-buff (&rest body)
|
||||||
"Execute BODY while at the end the log-buffer.
|
"Execute BODY while at the end the log-buffer.
|
||||||
|
@ -1810,8 +1830,8 @@ These are substituted with a normal 'set' op."
|
||||||
(defun comp-compile-ctxt-to-file (name)
|
(defun comp-compile-ctxt-to-file (name)
|
||||||
"Compile as native code the current context naming it NAME.
|
"Compile as native code the current context naming it NAME.
|
||||||
Prepare every function for final compilation and drive the C back-end."
|
Prepare every function for final compilation and drive the C back-end."
|
||||||
(cl-assert (= (length (comp-ctxt-data-relocs-l comp-ctxt))
|
(comp-data-container-check (comp-ctxt-d-base comp-ctxt))
|
||||||
(hash-table-count (comp-ctxt-data-relocs-idx comp-ctxt))))
|
(comp-data-container-check (comp-ctxt-d-impure comp-ctxt))
|
||||||
(comp--compile-ctxt-to-file name))
|
(comp--compile-ctxt-to-file name))
|
||||||
|
|
||||||
(defun comp-final (_)
|
(defun comp-final (_)
|
||||||
|
|
110
src/comp.c
110
src/comp.c
|
@ -39,9 +39,11 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
#define CURRENT_THREAD_RELOC_SYM "current_thread_reloc"
|
#define CURRENT_THREAD_RELOC_SYM "current_thread_reloc"
|
||||||
#define PURE_RELOC_SYM "pure_reloc"
|
#define PURE_RELOC_SYM "pure_reloc"
|
||||||
#define DATA_RELOC_SYM "d_reloc"
|
#define DATA_RELOC_SYM "d_reloc"
|
||||||
|
#define DATA_RELOC_IMPURE_SYM "d_reloc_imp"
|
||||||
#define FUNC_LINK_TABLE_SYM "freloc_link_table"
|
#define FUNC_LINK_TABLE_SYM "freloc_link_table"
|
||||||
#define LINK_TABLE_HASH_SYM "freloc_hash"
|
#define LINK_TABLE_HASH_SYM "freloc_hash"
|
||||||
#define TEXT_DATA_RELOC_SYM "text_data_reloc"
|
#define TEXT_DATA_RELOC_SYM "text_data_reloc"
|
||||||
|
#define TEXT_DATA_RELOC_IMPURE_SYM "text_data_reloc_imp"
|
||||||
|
|
||||||
#define SPEED XFIXNUM (Fsymbol_value (Qcomp_speed))
|
#define SPEED XFIXNUM (Fsymbol_value (Qcomp_speed))
|
||||||
#define COMP_DEBUG XFIXNUM (Fsymbol_value (Qcomp_debug))
|
#define COMP_DEBUG XFIXNUM (Fsymbol_value (Qcomp_debug))
|
||||||
|
@ -171,8 +173,12 @@ typedef struct {
|
||||||
Lisp_Object exported_funcs_h; /* subr_name -> gcc_jit_function *. */
|
Lisp_Object exported_funcs_h; /* subr_name -> gcc_jit_function *. */
|
||||||
Lisp_Object imported_funcs_h; /* subr_name -> gcc_jit_field *reloc_field. */
|
Lisp_Object imported_funcs_h; /* subr_name -> gcc_jit_field *reloc_field. */
|
||||||
Lisp_Object emitter_dispatcher;
|
Lisp_Object emitter_dispatcher;
|
||||||
gcc_jit_rvalue *data_relocs; /* Synthesized struct holding data relocs. */
|
/* Synthesized struct holding data relocs. */
|
||||||
gcc_jit_lvalue *func_relocs; /* Synthesized struct holding func relocs. */
|
gcc_jit_rvalue *data_relocs;
|
||||||
|
/* Same as before but can't go in pure space. */
|
||||||
|
gcc_jit_rvalue *data_relocs_impure;
|
||||||
|
/* Synthesized struct holding func relocs. */
|
||||||
|
gcc_jit_lvalue *func_relocs;
|
||||||
} comp_t;
|
} comp_t;
|
||||||
|
|
||||||
static comp_t comp;
|
static comp_t comp;
|
||||||
|
@ -894,9 +900,10 @@ emit_const_lisp_obj (Lisp_Object obj, Lisp_Object impure)
|
||||||
comp.void_ptr_type,
|
comp.void_ptr_type,
|
||||||
NULL));
|
NULL));
|
||||||
|
|
||||||
Lisp_Object d_reloc_idx = CALL1I (comp-ctxt-data-relocs-idx, Vcomp_ctxt);
|
Lisp_Object container = impure ? CALL1I (comp-ctxt-d-impure, Vcomp_ctxt)
|
||||||
Lisp_Object packed_obj = Fcons (impure, obj);
|
: CALL1I (comp-ctxt-d-base, Vcomp_ctxt);
|
||||||
Lisp_Object reloc_idx = Fgethash (packed_obj, d_reloc_idx, Qnil);
|
Lisp_Object reloc_idx =
|
||||||
|
Fgethash (obj, CALL1I (comp-data-container-idx, container), Qnil);
|
||||||
eassert (!NILP (reloc_idx));
|
eassert (!NILP (reloc_idx));
|
||||||
gcc_jit_rvalue *reloc_n =
|
gcc_jit_rvalue *reloc_n =
|
||||||
gcc_jit_context_new_rvalue_from_int (comp.ctxt,
|
gcc_jit_context_new_rvalue_from_int (comp.ctxt,
|
||||||
|
@ -906,7 +913,8 @@ emit_const_lisp_obj (Lisp_Object obj, Lisp_Object impure)
|
||||||
gcc_jit_lvalue_as_rvalue (
|
gcc_jit_lvalue_as_rvalue (
|
||||||
gcc_jit_context_new_array_access (comp.ctxt,
|
gcc_jit_context_new_array_access (comp.ctxt,
|
||||||
NULL,
|
NULL,
|
||||||
comp.data_relocs,
|
impure ? comp.data_relocs_impure
|
||||||
|
: comp.data_relocs,
|
||||||
reloc_n));
|
reloc_n));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1749,14 +1757,52 @@ emit_static_object (const char *name, Lisp_Object obj)
|
||||||
gcc_jit_block_end_with_return (block, NULL, res);
|
gcc_jit_block_end_with_return (block, NULL, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gcc_jit_rvalue *
|
||||||
|
declare_imported_data_relocs (Lisp_Object container, const char *code_symbol,
|
||||||
|
const char *text_symbol)
|
||||||
|
{
|
||||||
|
/* Imported objects. */
|
||||||
|
EMACS_INT d_reloc_len =
|
||||||
|
XFIXNUM (CALL1I (hash-table-count,
|
||||||
|
CALL1I (comp-data-container-idx, container)));
|
||||||
|
Lisp_Object d_reloc = Fnreverse (CALL1I (comp-data-container-l, container));
|
||||||
|
d_reloc = Fvconcat (1, &d_reloc);
|
||||||
|
|
||||||
|
gcc_jit_rvalue *reloc_struct =
|
||||||
|
gcc_jit_lvalue_as_rvalue (
|
||||||
|
gcc_jit_context_new_global (
|
||||||
|
comp.ctxt,
|
||||||
|
NULL,
|
||||||
|
GCC_JIT_GLOBAL_EXPORTED,
|
||||||
|
gcc_jit_context_new_array_type (comp.ctxt,
|
||||||
|
NULL,
|
||||||
|
comp.lisp_obj_type,
|
||||||
|
d_reloc_len),
|
||||||
|
code_symbol));
|
||||||
|
|
||||||
|
emit_static_object (text_symbol, d_reloc);
|
||||||
|
|
||||||
|
return reloc_struct;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
declare_runtime_imported_data (void)
|
declare_imported_data (void)
|
||||||
{
|
{
|
||||||
/* Imported symbols by inliner functions. */
|
/* Imported symbols by inliner functions. */
|
||||||
CALL1I (comp-add-const-to-relocs, Qnil);
|
CALL1I (comp-add-const-to-relocs, Qnil);
|
||||||
CALL1I (comp-add-const-to-relocs, Qt);
|
CALL1I (comp-add-const-to-relocs, Qt);
|
||||||
CALL1I (comp-add-const-to-relocs, Qconsp);
|
CALL1I (comp-add-const-to-relocs, Qconsp);
|
||||||
CALL1I (comp-add-const-to-relocs, Qlistp);
|
CALL1I (comp-add-const-to-relocs, Qlistp);
|
||||||
|
|
||||||
|
/* Imported objects. */
|
||||||
|
comp.data_relocs =
|
||||||
|
declare_imported_data_relocs (CALL1I (comp-ctxt-d-base, Vcomp_ctxt),
|
||||||
|
DATA_RELOC_SYM,
|
||||||
|
TEXT_DATA_RELOC_SYM);
|
||||||
|
comp.data_relocs_impure =
|
||||||
|
declare_imported_data_relocs (CALL1I (comp-ctxt-d-impure, Vcomp_ctxt),
|
||||||
|
DATA_RELOC_IMPURE_SYM,
|
||||||
|
TEXT_DATA_RELOC_IMPURE_SYM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1842,27 +1888,7 @@ emit_ctxt_code (void)
|
||||||
gcc_jit_type_get_pointer (comp.void_ptr_type),
|
gcc_jit_type_get_pointer (comp.void_ptr_type),
|
||||||
PURE_RELOC_SYM));
|
PURE_RELOC_SYM));
|
||||||
|
|
||||||
declare_runtime_imported_data ();
|
declare_imported_data ();
|
||||||
/* Imported objects. */
|
|
||||||
EMACS_INT d_reloc_len =
|
|
||||||
XFIXNUM (CALL1I (hash-table-count,
|
|
||||||
CALL1I (comp-ctxt-data-relocs-idx, Vcomp_ctxt)));
|
|
||||||
Lisp_Object d_reloc = Fnreverse (CALL1I (comp-ctxt-data-relocs-l, Vcomp_ctxt));
|
|
||||||
d_reloc = Fvconcat (1, &d_reloc);
|
|
||||||
|
|
||||||
comp.data_relocs =
|
|
||||||
gcc_jit_lvalue_as_rvalue (
|
|
||||||
gcc_jit_context_new_global (
|
|
||||||
comp.ctxt,
|
|
||||||
NULL,
|
|
||||||
GCC_JIT_GLOBAL_EXPORTED,
|
|
||||||
gcc_jit_context_new_array_type (comp.ctxt,
|
|
||||||
NULL,
|
|
||||||
comp.lisp_obj_type,
|
|
||||||
d_reloc_len),
|
|
||||||
DATA_RELOC_SYM));
|
|
||||||
|
|
||||||
emit_static_object (TEXT_DATA_RELOC_SYM, d_reloc);
|
|
||||||
|
|
||||||
/* Functions imported from Lisp code. */
|
/* Functions imported from Lisp code. */
|
||||||
freloc_check_fill ();
|
freloc_check_fill ();
|
||||||
|
@ -3263,12 +3289,14 @@ load_comp_unit (struct Lisp_Native_Comp_Unit *comp_u, bool loading_dump)
|
||||||
dynlib_sym (handle, CURRENT_THREAD_RELOC_SYM);
|
dynlib_sym (handle, CURRENT_THREAD_RELOC_SYM);
|
||||||
EMACS_INT ***pure_reloc = dynlib_sym (handle, PURE_RELOC_SYM);
|
EMACS_INT ***pure_reloc = dynlib_sym (handle, PURE_RELOC_SYM);
|
||||||
Lisp_Object *data_relocs = dynlib_sym (handle, DATA_RELOC_SYM);
|
Lisp_Object *data_relocs = dynlib_sym (handle, DATA_RELOC_SYM);
|
||||||
|
Lisp_Object *data_imp_relocs = dynlib_sym (handle, DATA_RELOC_IMPURE_SYM);
|
||||||
void **freloc_link_table = dynlib_sym (handle, FUNC_LINK_TABLE_SYM);
|
void **freloc_link_table = dynlib_sym (handle, FUNC_LINK_TABLE_SYM);
|
||||||
void (*top_level_run)(Lisp_Object) = dynlib_sym (handle, "top_level_run");
|
void (*top_level_run)(Lisp_Object) = dynlib_sym (handle, "top_level_run");
|
||||||
|
|
||||||
if (!(current_thread_reloc
|
if (!(current_thread_reloc
|
||||||
&& pure_reloc
|
&& pure_reloc
|
||||||
&& data_relocs
|
&& data_relocs
|
||||||
|
&& data_imp_relocs
|
||||||
&& freloc_link_table
|
&& freloc_link_table
|
||||||
&& top_level_run)
|
&& top_level_run)
|
||||||
|| NILP (Fstring_equal (load_static_obj (comp_u, LINK_TABLE_HASH_SYM),
|
|| 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)
|
||||||
|
|
||||||
/* Imported data. */
|
/* Imported data. */
|
||||||
if (!loading_dump)
|
if (!loading_dump)
|
||||||
comp_u->data_vec = load_static_obj (comp_u, TEXT_DATA_RELOC_SYM);
|
{
|
||||||
|
comp_u->data_vec = load_static_obj (comp_u, TEXT_DATA_RELOC_SYM);
|
||||||
|
comp_u->data_impure_vec =
|
||||||
|
load_static_obj (comp_u, TEXT_DATA_RELOC_IMPURE_SYM);
|
||||||
|
|
||||||
|
if (!NILP (Vpurify_flag))
|
||||||
|
/* Non impure can be copied into pure space. */
|
||||||
|
comp_u->data_vec = Fpurecopy (comp_u->data_vec);
|
||||||
|
}
|
||||||
|
|
||||||
EMACS_INT d_vec_len = XFIXNUM (Flength (comp_u->data_vec));
|
EMACS_INT d_vec_len = XFIXNUM (Flength (comp_u->data_vec));
|
||||||
|
|
||||||
if (!loading_dump && !NILP (Vpurify_flag))
|
|
||||||
for (EMACS_INT i = 0; i < d_vec_len; i++)
|
|
||||||
{
|
|
||||||
Lisp_Object packed_obj = AREF (comp_u->data_vec, i);
|
|
||||||
if (NILP (XCAR (packed_obj)))
|
|
||||||
/* If is not impure can be copied into pure space. */
|
|
||||||
XSETCDR (packed_obj, Fpurecopy (XCDR (packed_obj)));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (EMACS_INT i = 0; i < d_vec_len; i++)
|
for (EMACS_INT i = 0; i < d_vec_len; i++)
|
||||||
data_relocs[i] = XCDR (AREF (comp_u->data_vec, i));
|
data_relocs[i] = AREF (comp_u->data_vec, i);
|
||||||
|
|
||||||
|
d_vec_len = XFIXNUM (Flength (comp_u->data_impure_vec));
|
||||||
|
for (EMACS_INT i = 0; i < d_vec_len; i++)
|
||||||
|
data_imp_relocs[i] = AREF (comp_u->data_impure_vec, i);
|
||||||
|
|
||||||
if (!loading_dump)
|
if (!loading_dump)
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,6 +38,9 @@ struct Lisp_Native_Comp_Unit
|
||||||
Lisp_Object file;
|
Lisp_Object file;
|
||||||
/* Analogous to the constant vector but per compilation unit. */
|
/* Analogous to the constant vector but per compilation unit. */
|
||||||
Lisp_Object data_vec;
|
Lisp_Object data_vec;
|
||||||
|
/* Same but for data that cannot be moved to pure space.
|
||||||
|
Must be the last lisp object here. */
|
||||||
|
Lisp_Object data_impure_vec;
|
||||||
dynlib_handle_ptr handle;
|
dynlib_handle_ptr handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4767,8 +4767,8 @@ SUBR_NATIVE_COMPILEDP (Lisp_Object a)
|
||||||
INLINE struct Lisp_Native_Comp_Unit *
|
INLINE struct Lisp_Native_Comp_Unit *
|
||||||
allocate_native_comp_unit (void)
|
allocate_native_comp_unit (void)
|
||||||
{
|
{
|
||||||
return ALLOCATE_ZEROED_PSEUDOVECTOR (struct Lisp_Native_Comp_Unit, data_vec,
|
return ALLOCATE_ZEROED_PSEUDOVECTOR (struct Lisp_Native_Comp_Unit,
|
||||||
PVEC_NATIVE_COMP_UNIT);
|
data_impure_vec, PVEC_NATIVE_COMP_UNIT);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
INLINE bool
|
INLINE bool
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue